diff --git a/CMakeLists.txt b/CMakeLists.txt index e0ce21f..6be5b5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,6 +210,7 @@ set(VMIX_SRCS Source.cpp Session.cpp SessionVisitor.cpp + GarbageVisitor.cpp SessionCreator.cpp Mixer.cpp Settings.cpp diff --git a/GarbageVisitor.cpp b/GarbageVisitor.cpp new file mode 100644 index 0000000..b2925a8 --- /dev/null +++ b/GarbageVisitor.cpp @@ -0,0 +1,164 @@ +#include + +#include "Log.h" +#include "Scene.h" +#include "GarbageVisitor.h" + + +GarbageVisitor::GarbageVisitor(Node *nodetocollect) : Visitor() +{ + targets_.push_front(nodetocollect); + current_ = nullptr; + found_ == false; +} + +GarbageVisitor::GarbageVisitor(Source *sourcetocollect) : Visitor() +{ + targets_.push_front(sourcetocollect->group(View::MIXING)); + targets_.push_front(sourcetocollect->group(View::GEOMETRY)); + targets_.push_front(sourcetocollect->group(View::RENDERING)); + current_ = nullptr; + found_ == false; +} + + +void GarbageVisitor::visit(Node &n) +{ + // found the target +// if (n.id() == target_->id()) +// if ( &n == target_ ) + if ( std::count(targets_.begin(), targets_.end(), &n) ) + { + // end recursive + found_ = true; + + // take the node out of the Tree + if (current_) + current_->detatchChild(&n); + + } + +} + +GarbageVisitor::~GarbageVisitor() +{ + // actually delete the Node + +} + + +void GarbageVisitor::visit(Group &n) +{ + // no need to go further if the node was found (or is this group) + if (found_) + return; + + // current group + current_ = &n; + + // loop over members of a group + // and stop when found + for (NodeSet::iterator node = n.begin(); !found_ && node != n.end(); node++) { + // visit the child node + (*node)->accept(*this); + // un-stack recursive browsing + current_ = &n; + } + +} + +void GarbageVisitor::visit(Scene &n) +{ + n.root()->accept(*this); +} + +void GarbageVisitor::visit(Switch &n) +{ + +} + +void GarbageVisitor::visit(Animation &n) +{ + +} + +void GarbageVisitor::visit(Primitive &n) +{ + +} + +void GarbageVisitor::visit(Surface &n) +{ + +} + +void GarbageVisitor::visit(ImageSurface &n) +{ + +} + +void GarbageVisitor::visit(FrameBufferSurface &n) +{ + +} + +void GarbageVisitor::visit(MediaSurface &n) +{ + +} + +void GarbageVisitor::visit(MediaPlayer &n) +{ + +} + +void GarbageVisitor::visit(Shader &n) +{ + +} + +void GarbageVisitor::visit(ImageShader &n) +{ + +} + +void GarbageVisitor::visit(ImageProcessingShader &n) +{ + +} + +void GarbageVisitor::visit(LineStrip &n) +{ + +} + +void GarbageVisitor::visit(LineSquare &) +{ + +} + +void GarbageVisitor::visit(LineCircle &n) +{ + +} + +void GarbageVisitor::visit(Mesh &n) +{ + +} + +void GarbageVisitor::visit(Frame &n) +{ + +} + + +void GarbageVisitor::visit (Source& s) +{ + +} + +void GarbageVisitor::visit (MediaSource& s) +{ + +} diff --git a/GarbageVisitor.h b/GarbageVisitor.h new file mode 100644 index 0000000..6e2138d --- /dev/null +++ b/GarbageVisitor.h @@ -0,0 +1,47 @@ +#ifndef GARBAGEVISITOR_H +#define GARBAGEVISITOR_H + +#include + +#include "Source.h" +#include "Visitor.h" + + +class GarbageVisitor : public Visitor { + + Group *current_; + std::list targets_; + bool found_; + +public: + GarbageVisitor(Source *sourcetocollect); + GarbageVisitor(Node *nodetocollect); + ~GarbageVisitor(); + + void visit(Scene& n) override; + void visit(Node& n) override; + void visit(Group& n) override; + void visit(Switch& n) override; + void visit(Animation& n) override; + void visit(Primitive& n) override; + void visit(Surface& n) override; + void visit(ImageSurface& n) override; + void visit(MediaSurface& n) override; + void visit(FrameBufferSurface& n) override; + void visit(LineStrip& n) override; + void visit(LineSquare&) override; + void visit(LineCircle& n) override; + void visit(Mesh& n) override; + void visit(Frame& n) override; + + void visit(MediaPlayer& n) override; + void visit(Shader& n) override; + void visit(ImageShader& n) override; + void visit(ImageProcessingShader& n) override; + + void visit (Source& s) override; + void visit (MediaSource& s) override; + +}; + +#endif // GARBAGEVISITOR_H diff --git a/ImageProcessingShader.h b/ImageProcessingShader.h index 0283f6f..468aac8 100644 --- a/ImageProcessingShader.h +++ b/ImageProcessingShader.h @@ -11,7 +11,7 @@ class ImageProcessingShader : public Shader public: ImageProcessingShader(); - virtual ~ImageProcessingShader() {} +// virtual ~ImageProcessingShader() {} void use() override; void reset() override; diff --git a/ImageShader.cpp b/ImageShader.cpp index 1bdf7bb..d619ae0 100644 --- a/ImageShader.cpp +++ b/ImageShader.cpp @@ -5,7 +5,7 @@ #include "ImageShader.h" #include "Resource.h" -ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs"); +static ShadingProgram imageShadingProgram("shaders/image.vs", "shaders/image.fs"); const char* ImageShader::mask_names[10] = { "None", "Vignette", "Halo", "Circle", "Round", "Top", "Botton", "Left", "Right", "Custom" }; std::vector< uint > ImageShader::mask_presets; @@ -50,7 +50,7 @@ void ImageShader::reset() { Shader::reset(); - // setup double texturing + // setup double texturing (TODO : do it only once) program_->use(); program_->setUniform("iChannel0", 0); program_->setUniform("iChannel1", 1); diff --git a/ImageShader.h b/ImageShader.h index cfc0d67..97111e9 100644 --- a/ImageShader.h +++ b/ImageShader.h @@ -16,7 +16,7 @@ class ImageShader : public Shader public: ImageShader(); - virtual ~ImageShader() {} +// virtual ~ImageShader() {} void use() override; void reset() override; diff --git a/Mesh.cpp b/Mesh.cpp index 26b291c..1762041 100644 --- a/Mesh.cpp +++ b/Mesh.cpp @@ -333,22 +333,18 @@ Mesh::Mesh(const std::string& ply_path, const std::string& tex_path) : Primitive } // default non texture shader (deleted in Primitive) - shader_ = new Shader; + shader_ = new Shader(); } void Mesh::setTexture(uint textureindex) { if (textureindex) { - // replace previous shader with a new Image Shader - if (shader_) - delete shader_; - shader_ = new ImageShader; - + replaceShader( new ImageShader() ); + // set texture textureindex_ = textureindex; } - } void Mesh::init() diff --git a/Mixer.cpp b/Mixer.cpp index 252b825..54722f3 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -13,6 +13,7 @@ using namespace tinyxml2; #include "Settings.h" #include "SystemToolkit.h" #include "ImageProcessingShader.h" +#include "GarbageVisitor.h" #include "SessionVisitor.h" #include "SessionCreator.h" @@ -84,8 +85,35 @@ void Mixer::insertSource(Source *s) } void Mixer::deleteSource(Source *s) { +// SessionVisitor visit; +// geometry_.scene.accept(visit); +// visit.doc()->SaveFile("./geombefore.xml"); +// SessionVisitor visitm; +// mixing_.scene.accept(visitm); +// visitm.doc()->SaveFile("./mixbefore.xml"); + unsetCurrentSource(); + + // remove source Nodes from views +// GarbageVisitor mixingremover(s->group(View::MIXING)); +// mixingremover.visit(mixing_.scene); +// GarbageVisitor geomremover(s->group(View::GEOMETRY)); +// geomremover.visit(geometry_.scene); + + Log::Info("MIXING"); + mixing_.scene.root()->detatchChild( s->group(View::MIXING) ); + Log::Info("GEOMETRY"); + geometry_.scene.root()->detatchChild( s->group(View::GEOMETRY) ); + + // delete source session_->deleteSource(s); + +// SessionVisitor visit2; +// geometry_.scene.accept(visit2); +// visit2.doc()->SaveFile("./geomafter.xml"); +// SessionVisitor visit2m; +// mixing_.scene.accept(visit2m); +// visit2m.doc()->SaveFile("./mixmafter.xml"); } void Mixer::renameSource(Source *s, const std::string &newname) @@ -114,12 +142,19 @@ void Mixer::renameSource(Source *s, const std::string &newname) void Mixer::setCurrentSource(SourceList::iterator it) { - unsetCurrentSource(); + // nothing to do if already current + if ( current_source_ == it ) + return; + + // change current if ( it != session_->end() ) { current_source_ = it; current_source_index_ = session_->index(it); (*current_source_)->setOverlayVisible(true); } + // default + else + unsetCurrentSource(); } void Mixer::setCurrentSource(Node *node) @@ -217,6 +252,7 @@ void Mixer::save(const std::string& filename) for (iter = session_->begin(); iter != session_->end(); iter++) { SessionVisitor sv(&xmlDoc, session); + // source visitor (*iter)->accept(sv); } @@ -267,11 +303,11 @@ bool Mixer::open(const std::string& filename) newSession( new_session ); // insert nodes of sources into views - SourceList::iterator iter; - for (iter = new_session->begin(); iter != new_session->end(); iter++) + SourceList::iterator source_iter; + for (source_iter = new_session->begin(); source_iter != new_session->end(); source_iter++) { - mixing_.scene.root()->addChild( (*iter)->group(View::MIXING) ); - geometry_.scene.root()->addChild( (*iter)->group(View::GEOMETRY) ); + mixing_.scene.root()->addChild( (*source_iter)->group(View::MIXING) ); + geometry_.scene.root()->addChild( (*source_iter)->group(View::GEOMETRY) ); } } @@ -295,13 +331,25 @@ bool Mixer::open(const std::string& filename) void Mixer::newSession(Session *newsession) { - // TODO : remove roots of scenes for views? -// mixing_.scene.clear(); -// geometry_.scene.clear(); // delete session : delete all sources - if (session_) + if (session_) { + // remove nodes from views + for (auto source_iter = session_->begin(); source_iter != session_->end(); source_iter++) + { +// GarbageVisitor mixingremover( (*source_iter)->group(View::MIXING) ); +// mixingremover.visit(mixing_.scene); +// GarbageVisitor geomremover( (*source_iter)->group(View::GEOMETRY) ); +// geomremover.visit(geometry_.scene); + + Log::Info("MIXING"); + mixing_.scene.root()->detatchChild( (*source_iter)->group(View::MIXING) ); + Log::Info("GEOMETRY"); + geometry_.scene.root()->detatchChild( (*source_iter)->group(View::GEOMETRY) ); + } + // clear session delete session_; + } // validate new session if (newsession) diff --git a/Primitives.cpp b/Primitives.cpp index ff28a4f..4ffa6b6 100644 --- a/Primitives.cpp +++ b/Primitives.cpp @@ -40,6 +40,11 @@ Surface::Surface(Shader *s) : Primitive(s), textureindex_(0) } +Surface::~Surface() +{ + +} + void Surface::init() { // use static unique vertex array object @@ -58,7 +63,7 @@ void Surface::init() // 2. remember global vertex array object unique_vao_ = vao_; unique_drawCount = drawCount_; - // 3. unique_vao_ will NOT be deleted because ImageSurface::deleteGLBuffers_() is empty + // 3. unique_vao_ will NOT be deleted } } @@ -283,6 +288,12 @@ void LineSquare::accept(Visitor& v) v.visit(*this); } +LineSquare::~LineSquare() +{ + if (shader_) + delete shader_; +} + LineCircle::LineCircle(glm::vec4 color, uint linewidth) : LineStrip(std::vector(), color, linewidth) { @@ -330,3 +341,9 @@ void LineCircle::accept(Visitor& v) v.visit(*this); } + +LineCircle::~LineCircle() +{ + if (shader_) + delete shader_; +} diff --git a/Primitives.h b/Primitives.h index 1f07228..db5f062 100644 --- a/Primitives.h +++ b/Primitives.h @@ -19,8 +19,6 @@ class FrameBuffer; */ class Surface : public Primitive { - void deleteGLBuffers_() override {} - public: Surface(Shader *s = new ImageShader); @@ -33,6 +31,7 @@ public: protected: uint textureindex_; + virtual ~Surface(); }; @@ -152,13 +151,13 @@ public: */ class LineSquare : public LineStrip { - void deleteGLBuffers_() override {} - public: LineSquare(glm::vec4 color, uint linewidth = 1); void init() override; void accept(Visitor& v) override; + + virtual ~LineSquare(); }; @@ -167,13 +166,13 @@ public: */ class LineCircle : public LineStrip { - void deleteGLBuffers_() override {} - public: LineCircle(glm::vec4 color, uint linewidth = 1); void init() override; void accept(Visitor& v) override; + + virtual ~LineCircle(); }; diff --git a/Scene.cpp b/Scene.cpp index 1ba6b7d..5608a78 100644 --- a/Scene.cpp +++ b/Scene.cpp @@ -3,8 +3,11 @@ #include "Shader.h" #include "Primitives.h" #include "Visitor.h" +#include "GarbageVisitor.h" #include "Log.h" +#include "SessionVisitor.h" + #include #include @@ -17,7 +20,7 @@ #include -Group *Scene::limbo = new Group; +//Group *Scene::limbo = new Group; glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale) { @@ -30,7 +33,7 @@ glm::mat4 transform(glm::vec3 translation, glm::vec3 rotation, glm::vec3 scale) } // Node -Node::Node() : initialized_(false), visible_(true) +Node::Node() : initialized_(false), visible_(true), refcount_(0) { // create unique id auto duration = std::chrono::system_clock::now().time_since_epoch(); @@ -61,16 +64,19 @@ void Node::accept(Visitor& v) // Primitive + Primitive::~Primitive() { - deleteGLBuffers_(); + if ( vao_ ) + glDeleteVertexArrays ( 1, &vao_); if (shader_) delete shader_; } void Primitive::init() { - deleteGLBuffers_(); + if ( vao_ ) + glDeleteVertexArrays ( 1, &vao_); // Vertex Array glGenVertexArrays( 1, &vao_ ); @@ -171,23 +177,21 @@ void Primitive::replaceShader( Shader *newshader ) } } -void Primitive::deleteGLBuffers_() -{ - if ( vao_ ) - glDeleteVertexArrays ( 1, &vao_); -} - // Group Group::~Group() { + Log::Info("Delete Group %d ", id()); for(NodeSet::iterator it = children_.begin(); it != children_.end(); ) { - // this group is not parent of that node anymore - (*it)->parents_.remove(this); + Log::Info(" Child %d (%d)", (*it)->id(), (*it)->refcount_); + (*it)->refcount_--; // if this group was the only remaining parent - if ( (*it)->parents_.size() < 1 ) - // put the child in limbo - Scene::limbo->addChild( *it ); + if ( (*it)->refcount_ < 1 ) { + + Log::Info(" Deleting %d (%d)", (*it)->id(), (*it)->refcount_); + // delete + delete (*it); + } // erase this iterator from the list it = children_.erase(it); } @@ -196,19 +200,33 @@ Group::~Group() void Group::addChild(Node *child) { children_.insert(child); - child->parents_.push_back(this); + child->refcount_++; + +// children_.push_back(child); // list test + +// child->parents_.push_back(this); } void Group::detatchChild(Node *child) { - NodeSet::iterator it = std::find_if(children_.begin(), children_.end(), hasId(child->id())); - if ( it != children_.end()) - { - child->parents_.remove(this); + Log::Info("Group %d (N=%d) detaching %d", id(), numChildren(), child->id()); + + // find the node with this id, and erase it out of the list of children + // NB: do NOT delete with remove : this takes all nodes with same depth (i.e. equal depth in set) + NodeSet::iterator it = std::find_if(children_.begin(), children_.end(), hasId(child->id())); + if ( it != children_.end()) { + // detatch child from group parent children_.erase(it); + child->refcount_--; +// // detatch parent from child +// (*it)->parents_.remove(this); } + +// children_.remove(child); + Log::Info("Group %d (N=%d)", id(), numChildren()); + } void Group::update( float dt ) @@ -294,11 +312,11 @@ void Switch::addChild(Node *child) setActiveChild(child); } -void Switch::detatchChild(Node *child) -{ - Group::detatchChild(child); - active_ = children_.begin(); -} +//void Switch::detatchChild(Node *child) +//{ +// Group::detatchChild(child); +// active_ = children_.begin(); +//} void Switch::unsetActiveChild () @@ -385,24 +403,30 @@ Scene::Scene(): root_(nullptr) Scene::~Scene() { - deleteNode(root_); +// deleteNode(root_); + } void Scene::deleteNode(Node *node) { - for(auto it = node->parents_.begin(); it != node->parents_.end();){ - (*it)->detatchChild(node); - } - limbo->addChild(node); + GarbageVisitor remover(node); + remover.visit(*this); + +// // remove this node to the list of chidren of all its parents +// for(auto parent = node->parents_.begin(); parent != node->parents_.end(); parent++){ +// (*parent)->children_.erase(node); +// } +// node->parents_.clear(); + +// limbo->addChild(node); } void Scene::update(float dt) { root_->update( dt ); - // remove nodes from limbo } void Scene::accept(Visitor& v) diff --git a/Scene.h b/Scene.h index 2d402ac..1774641 100644 --- a/Scene.h +++ b/Scene.h @@ -45,13 +45,11 @@ class Node { int id_; bool initialized_; - public: Node (); // unique identifyer generated at instanciation inline int id () const { return id_; } -// void detatch(); // must initialize the node before draw virtual void init() { initialized_ = true; } @@ -67,14 +65,14 @@ public: virtual void accept (Visitor& v); // public members, to manipulate with care - std::list parents_; bool visible_; + uint refcount_; glm::mat4 transform_; glm::vec3 scale_, rotation_, translation_; -protected: virtual ~Node (); + }; @@ -107,6 +105,7 @@ public: inline Shader *shader () const { return shader_; } void replaceShader (Shader* newshader); + virtual ~Primitive(); protected: Shader* shader_; uint vao_, drawMode_, drawCount_; @@ -114,8 +113,7 @@ protected: std::vector colors_; std::vector texCoords_; std::vector indices_; - virtual void deleteGLBuffers_(); - virtual ~Primitive(); + }; // @@ -131,6 +129,8 @@ struct z_comparator }; typedef std::multiset NodeSet; +//typedef std::list NodeSet; + struct hasId: public std::unary_function { inline bool operator()(const Node* e) const @@ -142,6 +142,7 @@ private: int _id; }; + /** * @brief The Group class contains a list of pointers to Nodes. * @@ -157,9 +158,11 @@ private: */ class Group : public Node { + friend class Scene; public: Group() : Node() {} + virtual ~Group(); virtual void update (float dt) override; virtual void accept (Visitor& v) override; @@ -172,10 +175,10 @@ public: NodeSet::iterator end(); uint numChildren() const; + protected: NodeSet children_; - // destructor - virtual ~Group(); + }; /** @@ -195,7 +198,7 @@ public: virtual void draw (glm::mat4 modelview, glm::mat4 projection) override; void addChild (Node *child) override; - void detatchChild (Node *child) override; +// void detatchChild (Node *child) override; void unsetActiveChild (); void setActiveChild (Node *child); @@ -257,8 +260,9 @@ public: // Node *find(int id); // void remove(Node *n); // - static void deleteNode(Node *node); - static Group *limbo; + void deleteNode(Node *node); + +// static Group *limbo; }; diff --git a/Session.cpp b/Session.cpp index 78a5cb8..3c28504 100644 --- a/Session.cpp +++ b/Session.cpp @@ -1,7 +1,9 @@ #include #include "defines.h" +#include "FrameBuffer.h" #include "Session.h" +#include "GarbageVisitor.h" Session::Session() { @@ -11,10 +13,8 @@ Session::~Session() { // delete all sources for(auto it = sources_.begin(); it != sources_.end(); ) { - // delete source - delete (*it); - // erase this iterator from the list - it = sources_.erase(it); + // erase this source from the list + it = deleteSource(*it); } } @@ -22,14 +22,15 @@ Session::~Session() // update all sources void Session::update(float dt) { - // render of all sources + // pre-render of all sources for( SourceList::iterator it = sources_.begin(); it != sources_.end(); it++){ (*it)->render( ); } + // update the scene tree render_.update(dt); - // always draw render view + // draw render view in Frame Buffer render_.draw(); } @@ -50,19 +51,24 @@ SourceList::iterator Session::deleteSource(Source *s) SourceList::iterator its = find(s); // ok, its in the list ! if (its != sources_.end()) { - // iterate backward to previous element in the list (hopefully exist) - its--; - // remove the source and delete it - sources_.remove(s); + // remove Node from the rendering scene +// GarbageVisitor remover(s->group(View::RENDERING)); +// remover.visit(render_.scene); + render_.scene.root()->detatchChild( s->group(View::RENDERING) ); + + // erase the source from the update list & get next element + its = sources_.erase(its); + + // delete the source : safe now delete s; - // return - return its; + // NB: GarbageVisitor ends here, and deletes the Group RENDERING } - return sources_.end(); + // return end of next element + return its; } diff --git a/Shader.h b/Shader.h index d0677ee..9f6a57e 100644 --- a/Shader.h +++ b/Shader.h @@ -41,7 +41,7 @@ class Shader public: Shader(); - virtual ~Shader() {} +// virtual ~Shader() {} // unique identifyer generated at instanciation inline int id () const { return id_; } diff --git a/Source.cpp b/Source.cpp index b8bd1fb..47d8235 100644 --- a/Source.cpp +++ b/Source.cpp @@ -50,12 +50,10 @@ Source::~Source() // all groups and their children are deleted in the scene // this includes rendersurface_ , overlay_, blendingshader_ and rendershader_ -// delete groups_[View::RENDERING]; -// delete groups_[View::MIXING]; -// delete groups_[View::GEOMETRY]; - Scene::deleteNode(groups_[View::RENDERING]); - Scene::deleteNode(groups_[View::MIXING]); - Scene::deleteNode(groups_[View::GEOMETRY]); + delete groups_[View::RENDERING]; + delete groups_[View::MIXING]; + delete groups_[View::GEOMETRY]; + groups_.clear(); } @@ -120,7 +118,9 @@ MediaSource::MediaSource(const std::string &name) : Source(name), uri_("") MediaSource::~MediaSource() { - delete mediasurface_; + // TODO delete media surface with visitor + //delete mediasurface_; + delete mediaplayer_; // TODO verify that all surfaces and node is deleted in Source destructor } @@ -162,7 +162,7 @@ void MediaSource::init() // rendershader_->iChannelResolution[0] = glm::vec3(mediaplayer()->width(), mediaplayer()->height(), 0.f); // create the surfaces to draw the frame buffer in the views - // TODO Provide the source specific effect shader + // TODO Provide the source custom effect shader rendersurface_ = new FrameBufferSurface(renderbuffer_, blendingshader_); groups_[View::RENDERING]->addChild(rendersurface_); groups_[View::GEOMETRY]->addChild(rendersurface_); diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 37e3236..7a30877 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -50,7 +50,8 @@ static TextEditor editor; -static std::thread FileDialogThread_; +//static std::thread *FileDialogThread_; +static bool FileDialogPending_ = false; static bool FileDialogFinished_ = false; static std::string FileDialogFilename_ = ""; @@ -60,7 +61,9 @@ void ShowAboutOpengl(bool* p_open); void ShowAbout(bool* p_open); static void FileDialogOpen(std::string path) -{ +{ + FileDialogPending_ = true; + char const * lTheOpenFileName; char const * lFilterPatterns[2] = { "*.vmx" }; @@ -313,6 +316,7 @@ void UserInterface::NewFrame() // handle FileDialog if (FileDialogFinished_) { FileDialogFinished_ = false; + FileDialogPending_ = false; Mixer::manager().open(FileDialogFilename_); } } @@ -320,7 +324,6 @@ void UserInterface::NewFrame() void UserInterface::Render() { // ImVec2 geometry(static_cast(Rendering::manager().Width()), static_cast(Rendering::manager().Height())); - // // file modal dialog // geometry.x *= 0.4f; // geometry.y *= 0.4f; @@ -332,8 +335,7 @@ void UserInterface::Render() // } // FileDialog::Instance()->CloseDialog(currentFileDialog.c_str()); // } - - FileDialog::RenderCurrent(); +// FileDialog::RenderCurrent(); // warning modal dialog Log::Render(); @@ -378,16 +380,16 @@ void UserInterface::Terminate() void UserInterface::showMenuFile() { // TODO : New - if (ImGui::MenuItem( ICON_FA_FILE " New", "Ctrl+W")) { + if (ImGui::MenuItem( ICON_FA_FILE " New", "Ctrl+W", false, !FileDialogPending_)) { Mixer::manager().newSession(); navigator.hidePannel(); } - if (ImGui::MenuItem( ICON_FA_FILE_UPLOAD " Open", "Ctrl+O")) { + if (ImGui::MenuItem( ICON_FA_FILE_UPLOAD " Open", "Ctrl+O", false, !FileDialogPending_)) { // launch file dialog to open a session file - FileDialogThread_ = std::thread(FileDialogOpen, "./"); + std::thread (FileDialogOpen, "./").detach(); navigator.hidePannel(); } - if (ImGui::MenuItem( ICON_FA_FILE_DOWNLOAD " Save", "Ctrl+S")) { + if (ImGui::MenuItem( ICON_FA_FILE_DOWNLOAD " Save", "Ctrl+S", false, !FileDialogPending_)) { // UserInterface::manager().OpenFileMedia(); } // TODO : Save As...