From da7ce52e2c511effc91b882d2e472f35cd63c178 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Wed, 17 Jun 2020 00:03:21 +0200 Subject: [PATCH] Fixed UserInterface selection of multiple sources. Cleared code for Source searching by nodes pointers. --- Mixer.cpp | 2 +- SearchVisitor.cpp | 5 ++++- Selection.cpp | 10 ++++++++++ Selection.h | 1 + Session.cpp | 4 ++-- Source.cpp | 23 +++++++++++------------ Source.h | 38 +++++++++++++++++++------------------- View.cpp | 9 ++++++--- 8 files changed, 54 insertions(+), 38 deletions(-) diff --git a/Mixer.cpp b/Mixer.cpp index 3394f66..5407ba7 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -366,7 +366,7 @@ void Mixer::renameSource(Source *s, const std::string &newname) // search for a source of the name 'tentativename' std::string basename = tentativename; int count = 1; - while ( std::find_if(session_->begin(), session_->end(), hasName(tentativename)) != session_->end() ) { + while ( std::find_if(session_->begin(), session_->end(), Source::hasName(tentativename)) != session_->end() ) { tentativename = basename + std::to_string(++count); } diff --git a/SearchVisitor.cpp b/SearchVisitor.cpp index fad381b..fa4bc02 100644 --- a/SearchVisitor.cpp +++ b/SearchVisitor.cpp @@ -10,13 +10,16 @@ SearchVisitor::SearchVisitor(Node *node) : Visitor(), node_(node), found_(false) void SearchVisitor::visit(Node &n) { - if ( node_ == &n ){ + if ( !found_ && node_ == &n ){ found_ = true; } } void SearchVisitor::visit(Group &n) { + if (found_) + return; + for (NodeSet::iterator node = n.begin(); node != n.end(); node++) { (*node)->accept(*this); if (found_) diff --git a/Selection.cpp b/Selection.cpp index 33d7a85..58bf64d 100644 --- a/Selection.cpp +++ b/Selection.cpp @@ -21,6 +21,8 @@ void Selection::set(SourceList l) for(auto it = l.begin(); it != l.end(); it++) (*it)->setMode(Source::ACTIVE); + l.sort(); + l.unique(); selection_ = l; } @@ -32,7 +34,10 @@ void Selection::add(SourceList l) // generate new set as union of current selection and give list SourceList result; std::set_union(selection_.begin(), selection_.end(), l.begin(), l.end(), std::inserter(result, result.begin()) ); + // set new selection + result.sort(); + result.unique(); selection_ = SourceList(result); } @@ -65,6 +70,11 @@ void Selection::clear() selection_.clear(); } +uint Selection::size() +{ + return selection_.size(); +} + SourceList::iterator Selection::find(Source *s) { return std::find(selection_.begin(), selection_.end(), s); diff --git a/Selection.h b/Selection.h index b62ad88..04247a9 100644 --- a/Selection.h +++ b/Selection.h @@ -16,6 +16,7 @@ public: void set (SourceList l); void clear (); + uint size (); SourceList::iterator begin (); SourceList::iterator end (); diff --git a/Session.cpp b/Session.cpp index 697816b..b7cb7fb 100644 --- a/Session.cpp +++ b/Session.cpp @@ -151,12 +151,12 @@ SourceList::iterator Session::find(Source *s) SourceList::iterator Session::find(std::string namesource) { - return std::find_if(sources_.begin(), sources_.end(), hasName(namesource)); + return std::find_if(sources_.begin(), sources_.end(), Source::hasName(namesource)); } SourceList::iterator Session::find(Node *node) { - return std::find_if(sources_.begin(), sources_.end(), hasNode(node)); + return std::find_if(sources_.begin(), sources_.end(), Source::hasNode(node)); } uint Session::numSource() const diff --git a/Source.cpp b/Source.cpp index ad19905..704e77e 100644 --- a/Source.cpp +++ b/Source.cpp @@ -275,22 +275,21 @@ bool Source::contains(Node *node) const } -bool hasNode::operator()(const Source* elem) const +bool Source::hasNode::operator()(const Source* elem) const { if (_n && elem) { + // quick case (most frequent and easy to answer) + if (elem->rendersurface_ == _n) + return true; + + // general case: traverse tree of all Groups recursively using a SearchVisitor SearchVisitor sv(_n); - elem->group(View::MIXING)->accept(sv); - if (sv.found()) - return true; - elem->group(View::GEOMETRY)->accept(sv); - if (sv.found()) - return true; - elem->group(View::LAYER)->accept(sv); - if (sv.found()) - return true; - elem->group(View::RENDERING)->accept(sv); - return sv.found(); + for (auto g = elem->groups_.begin(); g != elem->groups_.end(); g++) { + (*g).second->accept(sv); + if (sv.found()) + return true; + } } return false; diff --git a/Source.h b/Source.h index 34625ee..8aa63de 100644 --- a/Source.h +++ b/Source.h @@ -85,6 +85,25 @@ public: // a Source shall define how to render into the frame buffer virtual void render() = 0; + + struct hasNode: public std::unary_function + { + bool operator()(const Source* elem) const; + hasNode(Node *n) : _n(n) { } + private: + Node *_n; + }; + + struct hasName: public std::unary_function + { + inline bool operator()(const Source* elem) const { + return (elem && elem->name() == _n); + } + hasName(std::string n) : _n(n) { } + private: + std::string _n; + }; + protected: // name std::string name_; @@ -128,25 +147,6 @@ protected: CloneList clones_; }; -struct hasName: public std::unary_function -{ - inline bool operator()(const Source* elem) const { - return (elem && elem->name() == _n); - } - hasName(std::string n) : _n(n) { } - -private: - std::string _n; -}; - -struct hasNode: public std::unary_function -{ - bool operator()(const Source* elem) const; - hasNode(Node *n) : _n(n) { } - -private: - Node *_n; -}; class CloneSource : public Source diff --git a/View.cpp b/View.cpp index 66d30b3..d36c677 100644 --- a/View.cpp +++ b/View.cpp @@ -120,16 +120,19 @@ void View::select(glm::vec2 A, glm::vec2 B) // picking visitor found nodes in the area? if ( !pv.picked().empty()) { + // create a list of source matching the list of picked nodes SourceList selection; - for(auto p = pv.picked().begin(); p != pv.picked().end(); p++){ + std::vector< std::pair > pick = pv.picked(); + // loop over the nodes and add all sources found. + for(std::vector< std::pair >::iterator p = pick.begin(); p != pick.end(); p++){ Source *s = Mixer::manager().findSource( p->first ); if (s) selection.push_back( s ); } // set the selection with list of picked (overlaped) sources - Mixer::selection().add(selection); - + Mixer::selection().set(selection); } + }