From 5aaa49c515aa45f6128f6ac25e813ce200288ceb Mon Sep 17 00:00:00 2001 From: Mike Solar Date: Mon, 10 Nov 2025 13:57:04 +0800 Subject: [PATCH] Add push button support for OFX plugins This commit adds support for push buttons in OFX plugins by: - Adding `kPushButton` to `NodeValue` enum - Implementing `pushButtonClicked` slot in `PluginNode` - Creating `NodeParamButton` widget for UI representation - Updating `paraminstance.h` to handle push button instances - Modifying `nodeparamviewwidgetbridge.cpp` to connect push button signals --- app/CMakeLists.txt | 2 + app/node/plugins/Plugin.cpp | 22 ++--- app/node/plugins/Plugin.h | 4 + app/node/value.h | 4 + app/pluginSupport/paraminstance.h | 88 +++++++++++++------ app/render/job/pluginjob.h | 7 +- app/widget/nodeparamview/CMakeLists.txt | 50 ++++++----- app/widget/nodeparamview/nodeparambutton.cpp | 20 +++++ app/widget/nodeparamview/nodeparambutton.h | 47 ++++++++++ .../nodeparamviewwidgetbridge.cpp | 10 +++ 10 files changed, 188 insertions(+), 66 deletions(-) create mode 100644 app/widget/nodeparamview/nodeparambutton.cpp create mode 100644 app/widget/nodeparamview/nodeparambutton.h diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index f3a57ec33..cb36f0ee5 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -57,6 +57,8 @@ set(OLIVE_RESOURCES ${CMAKE_CURRENT_BINARY_DIR}/ts/translations.qrc render/job/pluginjob.cpp render/job/pluginjob.h + widget/nodeparamview/nodeparambutton.cpp + widget/nodeparamview/nodeparambutton.h ) # Add version object diff --git a/app/node/plugins/Plugin.cpp b/app/node/plugins/Plugin.cpp index af663eb71..e74a86aab 100644 --- a/app/node/plugins/Plugin.cpp +++ b/app/node/plugins/Plugin.cpp @@ -53,20 +53,20 @@ olive::plugin::PluginNode::PluginNode( } else if (ofxType == kOfxParamTypeStrChoice){ type = NodeValue::kStrCombo; }else if (ofxType == kOfxParamTypeBytes - || ofxType == kOfxParamTypeCustom) { + || ofxType == kOfxParamTypeCustom) { type = NodeValue::kBinary; - } else { - type = NodeValue::kNone; - } - - if (ofxType == kOfxParamTypePushButton) { - // TODO + } else if (ofxType == kOfxParamTypePushButton) { + type = NodeValue::kPushButton; } else if (ofxType == kOfxParamTypeGroup) { // TODO } else if (ofxType == kOfxParamTypePage) { // TODO + }else { + type = NodeValue::kNone; } + + AddInput(param.second->getName().data(), type); } @@ -91,12 +91,12 @@ void olive::plugin::PluginNode::Value(const NodeValueRow &value, { TexturePtr tex = value[kTextureInput].toTexture(); if (tex) { - PluginJob job(,value); + PluginJob job(plugin, value); table->Push(NodeValue::kTexture, tex->toJob(job), this); } - - - +} +void olive::plugin::PluginNode::pushButtonClicked(QString name) +{ } QString olive::plugin::PluginNode::id() const diff --git a/app/node/plugins/Plugin.h b/app/node/plugins/Plugin.h index b2ab6b5fd..490a9d97f 100644 --- a/app/node/plugins/Plugin.h +++ b/app/node/plugins/Plugin.h @@ -40,6 +40,7 @@ public: void AddPushButton(); void AddPage(); + Node *copy() const override; /** * @brief The main processing function @@ -73,6 +74,9 @@ public: */ virtual void GenerateFrame(FramePtr frame, const GenerateJob &job) const; +public slots: + void pushButtonClicked(QString name); + }; } diff --git a/app/node/value.h b/app/node/value.h index 43f370bf4..5f1ff9d7b 100644 --- a/app/node/value.h +++ b/app/node/value.h @@ -197,6 +197,10 @@ public: kBinary, /** + *Push Button + */ + kPushButton, + /** * End of list */ kDataTypeCount diff --git a/app/pluginSupport/paraminstance.h b/app/pluginSupport/paraminstance.h index 9a05ecaa5..e7b746dcd 100644 --- a/app/pluginSupport/paraminstance.h +++ b/app/pluginSupport/paraminstance.h @@ -21,20 +21,21 @@ #ifndef PARAM_INSTANCE_H #define PARAM_INSTANCE_H -#include "OlivePluginInstance.h" #include "ofxhParam.h" +#include "node/plugins/Plugin.h" namespace olive { namespace plugin { class PushbuttonInstance : public OFX::Host::Param::PushbuttonInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor *_descriptor; public: - PushbuttonInstance(OlivePluginInstance *effect, const std::string &name, + PushbuttonInstance(PluginNode *effect, const std::string &name, OFX::Host::Param::Descriptor &descriptor) - : OFX::Host::Param::PushbuttonInstance( descriptor) + : OFX::Host::Param::PushbuttonInstance(descriptor) + , node(effect) { _descriptor = &descriptor; }; @@ -42,22 +43,58 @@ public: class IntegerInstance : public OFX::Host::Param::IntegerInstance { protected: - OlivePluginInstance* _effect; + PluginNode* _node; OFX::Host::Param::Descriptor& _descriptor; + QString id; public: - IntegerInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); - OfxStatus get(int&); - OfxStatus get(OfxTime time, int&); - OfxStatus set(int); - OfxStatus set(OfxTime time, int); + IntegerInstance(PluginNode *node, OFX::Host::Param::Descriptor &descriptor) + : _node(node), _descriptor(descriptor), + OFX::Host::Param::IntegerInstance(_descriptor){} + OfxStatus get(int &a) + { + if (id.isEmpty()) { + return kOfxStatErrBadHandle; + } + QVariant variant=_node->GetStandardValue(id); + + if (variant.typeId()==QVariant::Int) { + a=variant.toInt(); + return kOfxStatOK; + } + a=0; + return kOfxStatErrValue; + } + OfxStatus get(OfxTime time, int &data) + { + if (id.isEmpty()) { + return kOfxStatErrBadHandle; + } + QVariant variant=_node->GetValueAtTime(id, rational::fromDouble(time)); + if (variant.typeId()==QVariant::Int) { + data=variant.toInt(); + return kOfxStatOK; + } + data=0; + return kOfxStatErrValue; + } + OfxStatus set(int data) + { + _node->SetStandardValue(_descriptor.getName().c_str(), data); + id=_descriptor.getName().c_str(); + return kOfxStatOK; + } + OfxStatus set(OfxTime time, int) + { + _node->SetValueAtTime() + } }; class DoubleInstance : public OFX::Host::Param::DoubleInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - DoubleInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + DoubleInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(double&); OfxStatus get(OfxTime time, double&); OfxStatus set(double); @@ -68,10 +105,10 @@ public: class BooleanInstance : public OFX::Host::Param::BooleanInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - BooleanInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + BooleanInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(bool&); OfxStatus get(OfxTime time, bool&); OfxStatus set(bool); @@ -80,10 +117,10 @@ public: class ChoiceInstance : public OFX::Host::Param::ChoiceInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - ChoiceInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + ChoiceInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(int&); OfxStatus get(OfxTime time, int&); OfxStatus set(int); @@ -92,10 +129,10 @@ public: class RGBAInstance : public OFX::Host::Param::RGBAInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - RGBAInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + RGBAInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(double&,double&,double&,double&); OfxStatus get(OfxTime time, double&,double&,double&,double&); OfxStatus set(double,double,double,double); @@ -105,10 +142,10 @@ public: class RGBInstance : public OFX::Host::Param::RGBInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - RGBInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + RGBInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(double&,double&,double&); OfxStatus get(OfxTime time, double&,double&,double&); OfxStatus set(double,double,double); @@ -117,10 +154,10 @@ public: class Double2DInstance : public OFX::Host::Param::Double2DInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - Double2DInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + Double2DInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(double&,double&); OfxStatus get(OfxTime time,double&,double&); OfxStatus set(double,double); @@ -129,10 +166,10 @@ public: class Integer2DInstance : public OFX::Host::Param::Integer2DInstance { protected: - OlivePluginInstance* _effect; + PluginNode* node; OFX::Host::Param::Descriptor& _descriptor; public: - Integer2DInstance(OlivePluginInstance* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); + Integer2DInstance(PluginNode* effect, const std::string& name, OFX::Host::Param::Descriptor& descriptor); OfxStatus get(int&,int&); OfxStatus get(OfxTime time,int&,int&); OfxStatus set(int,int); @@ -144,6 +181,3 @@ public: #endif // HOST_DEMO_PARAM_INSTANCE_H - - -#endif //PARAMINSTANCE_H diff --git a/app/render/job/pluginjob.h b/app/render/job/pluginjob.h index 84d945469..757d0cfce 100644 --- a/app/render/job/pluginjob.h +++ b/app/render/job/pluginjob.h @@ -23,21 +23,20 @@ #include "pluginSupport/OlivePluginInstance.h" #include +#include namespace olive { namespace plugin { class PluginJob :public AcceleratedJob{ public: - explicit PluginJob(std::shared_ptr pluginInstance, NodeValueRow row): AcceleratedJob() + explicit PluginJob(OFX::Host::ImageEffect::ImageEffectPlugin* pluginInstance, NodeValueRow row): AcceleratedJob() { this->pluginInstance = pluginInstance; - - } private: - std::shared_ptr pluginInstance; + OFX::Host::ImageEffect::ImageEffectPlugin *pluginInstance=nullptr; QHash> paramsOnTime; diff --git a/app/widget/nodeparamview/CMakeLists.txt b/app/widget/nodeparamview/CMakeLists.txt index 1b80edebc..4f7cf658e 100644 --- a/app/widget/nodeparamview/CMakeLists.txt +++ b/app/widget/nodeparamview/CMakeLists.txt @@ -15,28 +15,30 @@ # along with this program. If not, see . set(OLIVE_SOURCES - ${OLIVE_SOURCES} - widget/nodeparamview/nodeparamview.cpp - widget/nodeparamview/nodeparamview.h - widget/nodeparamview/nodeparamviewarraywidget.cpp - widget/nodeparamview/nodeparamviewarraywidget.h - widget/nodeparamview/nodeparamviewconnectedlabel.cpp - widget/nodeparamview/nodeparamviewconnectedlabel.h - widget/nodeparamview/nodeparamviewcontext.cpp - widget/nodeparamview/nodeparamviewcontext.h - widget/nodeparamview/nodeparamviewdockarea.cpp - widget/nodeparamview/nodeparamviewdockarea.h - widget/nodeparamview/nodeparamviewitem.cpp - widget/nodeparamview/nodeparamviewitem.h - widget/nodeparamview/nodeparamviewitembase.cpp - widget/nodeparamview/nodeparamviewitembase.h - widget/nodeparamview/nodeparamviewitemtitlebar.cpp - widget/nodeparamview/nodeparamviewitemtitlebar.h - widget/nodeparamview/nodeparamviewkeyframecontrol.cpp - widget/nodeparamview/nodeparamviewkeyframecontrol.h - widget/nodeparamview/nodeparamviewtextedit.cpp - widget/nodeparamview/nodeparamviewtextedit.h - widget/nodeparamview/nodeparamviewwidgetbridge.cpp - widget/nodeparamview/nodeparamviewwidgetbridge.h - PARENT_SCOPE + ${OLIVE_SOURCES} + widget/nodeparamview/nodeparamview.cpp + widget/nodeparamview/nodeparamview.h + widget/nodeparamview/nodeparamviewarraywidget.cpp + widget/nodeparamview/nodeparamviewarraywidget.h + widget/nodeparamview/nodeparamviewconnectedlabel.cpp + widget/nodeparamview/nodeparamviewconnectedlabel.h + widget/nodeparamview/nodeparamviewcontext.cpp + widget/nodeparamview/nodeparamviewcontext.h + widget/nodeparamview/nodeparamviewdockarea.cpp + widget/nodeparamview/nodeparamviewdockarea.h + widget/nodeparamview/nodeparamviewitem.cpp + widget/nodeparamview/nodeparamviewitem.h + widget/nodeparamview/nodeparamviewitembase.cpp + widget/nodeparamview/nodeparamviewitembase.h + widget/nodeparamview/nodeparamviewitemtitlebar.cpp + widget/nodeparamview/nodeparamviewitemtitlebar.h + widget/nodeparamview/nodeparamviewkeyframecontrol.cpp + widget/nodeparamview/nodeparamviewkeyframecontrol.h + widget/nodeparamview/nodeparamviewtextedit.cpp + widget/nodeparamview/nodeparamviewtextedit.h + widget/nodeparamview/nodeparamviewwidgetbridge.cpp + widget/nodeparamview/nodeparamviewwidgetbridge.h + widget/nodeparamview/nodeparambutton.h + widget/nodeparamview/nodeparambutton.cpp + PARENT_SCOPE ) diff --git a/app/widget/nodeparamview/nodeparambutton.cpp b/app/widget/nodeparamview/nodeparambutton.cpp new file mode 100644 index 000000000..2696e6d98 --- /dev/null +++ b/app/widget/nodeparamview/nodeparambutton.cpp @@ -0,0 +1,20 @@ +/* + * Olive Community Edition - Non-Linear Video Editor + * Copyright (C) 2025 Olive CE Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#include "nodeparambutton.h" diff --git a/app/widget/nodeparamview/nodeparambutton.h b/app/widget/nodeparamview/nodeparambutton.h new file mode 100644 index 000000000..cb06ce7f1 --- /dev/null +++ b/app/widget/nodeparamview/nodeparambutton.h @@ -0,0 +1,47 @@ +/* + * Olive Community Edition - Non-Linear Video Editor + * Copyright (C) 2025 Olive CE Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#ifndef NODEPARAMBUTTON_H +#define NODEPARAMBUTTON_H +#include "node/plugins/Plugin.h" + +#include + +class NodeParamButton : public QPushButton{ +Q_OBJECT +public: + NodeParamButton(QString name, QWidget *parent = nullptr):QPushButton(parent) + { + this->name_=name; + connect(this, &QPushButton::clicked, this, &NodeParamButton::pressed); + } +signals: + void onPressed(QString name); +private slots: + void pressed(){ + emit onPressed(name_); + } +private: + QString name_; + +}; + + + +#endif //NODEPARAMBUTTON_H diff --git a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp index a9236698c..9f8eb4399 100644 --- a/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp +++ b/app/widget/nodeparamview/nodeparamviewwidgetbridge.cpp @@ -26,6 +26,7 @@ #include "common/qtutils.h" #include "core.h" +#include "nodeparambutton.h" #include "node/group/group.h" #include "node/node.h" #include "node/nodeundo.h" @@ -40,6 +41,8 @@ #include "widget/slider/integerslider.h" #include "widget/slider/rationalslider.h" +#include + namespace olive { @@ -179,6 +182,13 @@ void NodeParamViewWidgetBridge::CreateWidgets() &NodeParamViewWidgetBridge::WidgetCallback); break; } + case NodeValue::kPushButton: { + NodeInput input=GetInnerInput(); + NodeParamButton *button=new NodeParamButton(input.name(),parent); + widgets_.append(button); + plugin::PluginNode* plugin_node=dynamic_cast(input.node()); + connect(button, &NodeParamButton::onPressed, plugin_node, &plugin::PluginNode::pushButtonClicked); + } } // Check all properties