Draft implementation of Following mechanism for Image processing

This commit is contained in:
brunoherbelin
2021-04-06 23:20:13 +02:00
parent 1d45ab1d20
commit 788fa693fd
5 changed files with 160 additions and 21 deletions

View File

@@ -473,9 +473,16 @@ void ImGuiVisitor::visit (Source& s)
ImGui::OpenPopup( "MenuImageProcessing" );
if (ImGui::BeginPopup( "MenuImageProcessing" ))
{
if (s.processingshader_link_.connected()) {
if (ImGui::MenuItem( "Unfollow" )){
s.processingshader_link_.disconnect();
}
}
else {
if (ImGui::MenuItem("Reset" )){
ImageProcessingShader defaultvalues;
s.processingShader()->copy(defaultvalues);
s.processingshader_link_.disconnect();
std::ostringstream oss;
oss << s.name() << ": " << "Reset Filter";
Action::manager().store(oss.str());
@@ -493,12 +500,42 @@ void ImGuiVisitor::visit (Source& s)
oss << s.name() << ": " << "Change Filter";
Action::manager().store(oss.str());
}
ImGui::Separator();
if (ImGui::BeginMenu("Follow"))
{
for (auto mpit = Mixer::manager().session()->begin();
mpit != Mixer::manager().session()->end(); mpit++ )
{
std::string label = (*mpit)->name();
if ( (*mpit)->id() != s.id() &&
(*mpit)->imageProcessingEnabled() &&
!(*mpit)->processingshader_link_.connected()) {
if (ImGui::MenuItem( label.c_str() )){
s.processingshader_link_.connect(*mpit);
s.touch();
}
}
}
ImGui::EndMenu();
}
}
ImGui::EndPopup();
}
// full panel for image processing
ImGui::SetCursorPos( ImVec2( pos.x, pos.y + preview_height)); // ...come back
if (s.processingshader_link_.connected()) {
ImGuiToolkit::Icon(6, 2);
ImGui::SameLine(0, 10);
ImGui::Text("Filters");
Source *target = s.processingshader_link_.source();
ImGui::Text("Following");
if ( ImGui::Button(target->name().c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0)) )
Mixer::manager().setCurrentSource(target);
}
else
s.processingShader()->accept(*this);
}

View File

@@ -12,7 +12,6 @@
#include "ImageShader.h"
#include "ImageProcessingShader.h"
#include "SystemToolkit.h"
#include "SessionVisitor.h"
#include "Log.h"
#include "MixingGroup.h"
@@ -234,6 +233,10 @@ Source::Source() : initialized_(false), symbol_(nullptr), active_(true), locked_
Source::~Source()
{
// inform links that they lost their target
while ( !links_.empty() )
links_.front()->disconnect();
// inform clones that they lost their origin
for (auto it = clones_.begin(); it != clones_.end(); it++)
(*it)->detach();
@@ -649,6 +652,15 @@ void Source::update(float dt)
need_update_ = false;
}
if (processingshader_link_.connected() && imageProcessingEnabled()) {
Source *ref_source = processingshader_link_.source();
if (ref_source!=nullptr) {
if (ref_source->imageProcessingEnabled())
processingshader_->copy( *ref_source->processingShader() );
else
processingshader_link_.disconnect();
}
}
}
FrameBuffer *Source::frame() const
@@ -749,6 +761,7 @@ void Source::clearMixingGroup()
overlay_mixinggroup_->visible_ = false;
}
CloneSource *Source::clone()
{
CloneSource *s = new CloneSource(this);

View File

@@ -15,7 +15,6 @@ class MaskShader;
class ImageProcessingShader;
class FrameBuffer;
class FrameBufferSurface;
class Session;
class Frame;
class Handles;
class Symbol;
@@ -26,6 +25,7 @@ typedef std::list<CloneSource *> CloneList;
class Source
{
friend class SourceLink;
friend class CloneSource;
friend class View;
friend class MixingView;
@@ -198,6 +198,8 @@ public:
// class-dependent icon
virtual glm::ivec2 icon () const { return glm::ivec2(12, 11); }
SourceLink processingshader_link_;
protected:
// name
std::string name_;
@@ -263,6 +265,9 @@ protected:
// clones
CloneList clones_;
// links
SourceLinkList links_;
// Mixing
MixingGroup *mixinggroup_;
Switch *overlay_mixinggroup_;

View File

@@ -4,6 +4,8 @@
#include <glm/gtx/rotate_vector.hpp>
#include "Source.h"
#include "Session.h"
#include "SourceList.h"
// utility to sort Sources by depth
@@ -118,3 +120,64 @@ SourceList join (const SourceList &first, const SourceList &second)
return l;
}
void SourceLink::connect(uint64_t id, Session *se)
{
if (connected())
disconnect();
id_ = id;
host_ = se;
}
void SourceLink::connect(Source *s)
{
if (connected())
disconnect();
target_ = s;
id_ = s->id();
target_->links_.push_back(this);
// TODO veryfy circular dependency recursively ?
}
void SourceLink::disconnect()
{
if (target_)
target_->links_.remove(this);
id_ = 0;
target_ = nullptr;
host_ = nullptr;
}
SourceLink::~SourceLink()
{
disconnect();
}
Source *SourceLink::source()
{
// no link to pointer yet?
if ( target_ == nullptr ) {
// to find a source, we need a host and an id
if ( id_ > 0 && host_ != nullptr) {
// find target in session
SourceList::iterator it = host_->find(id_);
// found: keep pointer
if (it != host_->end()) {
target_ = *it;
target_->links_.push_back(this);
}
// not found: invalidate link
else
disconnect();
}
// no host: invalidate link
else
disconnect();
}
return target_;
}

View File

@@ -5,6 +5,7 @@
#include <glm/glm.hpp>
class Source;
class Session;
typedef std::list<Source *> SourceList;
@@ -25,4 +26,24 @@ SourceListCompare compare (const SourceList &first, const SourceList &second);
typedef std::list<uint64_t> SourceIdList;
SourceIdList ids (const SourceList &list);
class SourceLink {
public:
SourceLink(): host_(nullptr), target_(nullptr), id_(0) { }
~SourceLink();
void connect(uint64_t id, Session *se);
void connect(Source *s);
void disconnect();
bool connected() { return id_ > 0; }
Source *source();
protected:
Session *host_;
Source *target_;
uint64_t id_;
};
typedef std::list<SourceLink*> SourceLinkList;
#endif // SOURCELIST_H