diff --git a/SessionCreator.cpp b/SessionCreator.cpp index 4ac4a02..a9d80a7 100644 --- a/SessionCreator.cpp +++ b/SessionCreator.cpp @@ -23,54 +23,37 @@ using namespace tinyxml2; #include "SessionCreator.h" -std::string SessionCreator::info(const std::string& filename) +SessionInformation SessionCreator::info(const std::string& filename) { - std::string ret = ""; + SessionInformation ret; // if the file exists if (SystemToolkit::file_exists(filename)) { + // impose C locale + setlocale(LC_ALL, "C"); // try to load the file XMLDocument doc; XMLError eResult = doc.LoadFile(filename.c_str()); // silently ignore on error if ( !XMLResultError(eResult, false)) { - XMLElement *header = doc.FirstChildElement(APP_NAME); - if (header != nullptr && header->Attribute("date") != 0) { + const XMLElement *header = doc.FirstChildElement(APP_NAME); + if (header != nullptr) { int s = header->IntAttribute("size"); - ret = std::to_string( s ) + " source" + ( s > 1 ? "s\n" : "\n"); + ret.description = std::to_string( s ) + " source" + ( s > 1 ? "s\n" : "\n"); const char *att_string = header->Attribute("resolution"); if (att_string) - ret += std::string( att_string ) + "\n"; + ret.description += std::string( att_string ) + "\n"; att_string = header->Attribute("date"); if (att_string) { std::string date( att_string ); - ret += date.substr(6,2) + "/" + date.substr(4,2) + "/" + date.substr(0,4) + " @ "; - ret += date.substr(8,2) + ":" + date.substr(10,2); + ret.description += date.substr(6,2) + "/" + date.substr(4,2) + "/" + date.substr(0,4) + " @ "; + ret.description += date.substr(8,2) + ":" + date.substr(10,2); } - } - } - } - - return ret; -} - -FrameBufferImage *SessionCreator::thumbnail(const std::string& filename) -{ - FrameBufferImage *ret = nullptr; - - // if the file exists - if (SystemToolkit::file_exists(filename)) { - // try to load the file - XMLDocument doc; - XMLError eResult = doc.LoadFile(filename.c_str()); - // silently ignore on error - if ( !XMLResultError(eResult, false)) { - - XMLElement *header = doc.FirstChildElement("Session"); - if (header != nullptr ) { - ret = XMLToImage(header); + const XMLElement *session = doc.FirstChildElement("Session"); + if (session != nullptr ) { + ret.thumbnail = XMLToImage(session); } } } diff --git a/SessionCreator.h b/SessionCreator.h index a8ad4d5..95e242c 100644 --- a/SessionCreator.h +++ b/SessionCreator.h @@ -10,6 +10,7 @@ class Session; class FrameBufferImage; + class SessionLoader : public Visitor { SessionLoader(); @@ -76,6 +77,15 @@ protected: }; +struct SessionInformation { + std::string description; + FrameBufferImage *thumbnail; + SessionInformation() { + description = ""; + thumbnail = nullptr; + } +}; + class SessionCreator : public SessionLoader { tinyxml2::XMLDocument xmlDoc_; @@ -89,8 +99,7 @@ public: void load(const std::string& filename); - static std::string info(const std::string& filename); - static FrameBufferImage *thumbnail(const std::string& filename); + static SessionInformation info(const std::string& filename); }; #endif // SESSIONCREATOR_H diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 139d604..eddfdc2 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -2987,6 +2987,7 @@ void Navigator::RenderMainPannelVimix() { static std::list::iterator _file_over = sessions_list.end(); + static std::list::iterator _displayed_over = sessions_list.end(); static bool _tooltip = 0; // display the sessions list and detect if one was selected (double clic) @@ -3004,34 +3005,33 @@ void Navigator::RenderMainPannelVimix() std::string shortname = SystemToolkit::filename(*it); if (ImGui::Selectable( shortname.c_str(), false, ImGuiSelectableFlags_AllowDoubleClick, size )) { - // show tooltip on clic - _tooltip = true; - + // open on double clic if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left) /*|| file_selected == it*/) { Mixer::manager().open( *it, Settings::application.smooth_transition ); done = true; } + else + // show tooltip on clic + _tooltip = true; + } if (ImGui::IsItemHovered()) _file_over = it; if (_tooltip && _file_over != sessions_list.end() && count_over < 1) { - static std::list::iterator _displayed_over = sessions_list.end(); static std::string _file_info = ""; static Thumbnail _file_thumbnail; - // load info only if current changed + // load info only if changed from the one already displayed if (_displayed_over != _file_over) { _displayed_over = _file_over; - - _file_info = SessionCreator::info(*_displayed_over); - - FrameBufferImage *im = SessionCreator::thumbnail(*_displayed_over); - if (im) { + SessionInformation info = SessionCreator::info(*_displayed_over); + _file_info = info.description; + if (info.thumbnail) { // set image content to thumbnail display - _file_thumbnail.set( im ); - delete im; + _file_thumbnail.set( info.thumbnail ); + delete info.thumbnail; } else _file_thumbnail.reset(); } @@ -3056,7 +3056,7 @@ void Navigator::RenderMainPannelVimix() if (done) { hidePannel(); _tooltip = false; - _file_over = sessions_list.end(); + _displayed_over = _file_over = sessions_list.end(); // reload the list next time selection_session_mode_changed = true; } @@ -3064,7 +3064,7 @@ void Navigator::RenderMainPannelVimix() // cancel tooltip and mouse over on mouse exit if ( !ImGui::IsItemHovered()) { _tooltip = false; - _file_over = sessions_list.end(); + _displayed_over = _file_over = sessions_list.end(); } } @@ -3074,7 +3074,7 @@ void Navigator::RenderMainPannelVimix() // Right side of the list: helper and options ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y)); if ( ImGuiToolkit::IconButton( ICON_FA_FILE )) { - Mixer::manager().open( "", Settings::application.smooth_transition ); + Mixer::manager().close(Settings::application.smooth_transition ); hidePannel(); } if (ImGui::IsItemHovered()) @@ -3143,6 +3143,7 @@ void Navigator::RenderMainPannelVimix() if (Settings::application.pannel_history_mode > 0) { static uint _over = 0; + static uint64_t _displayed_over = 0; static bool _tooltip = 0; pos_top = ImGui::GetCursorPos(); @@ -3155,20 +3156,20 @@ void Navigator::RenderMainPannelVimix() for (uint i = Action::manager().max(); i > 0; --i) { if (ImGui::Selectable( Action::manager().label(i).c_str(), i == Action::manager().current(), ImGuiSelectableFlags_AllowDoubleClick, size )) { - // show tooltip on clic - _tooltip = true; + // go to on double clic if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Left)) Action::manager().stepTo(i); + else + // show tooltip on clic + _tooltip = true; } // mouse over - if (ImGui::IsItemHovered()) { + if (ImGui::IsItemHovered()) _over = i; - } // if mouse over (only once) if (_tooltip && _over > 0 && count_over < 1) { static std::string text = ""; - static uint64_t _displayed_over = 0; static Thumbnail _undo_thumbnail; // load label and thumbnail only if current changed if (_displayed_over != _over) { @@ -3199,7 +3200,7 @@ void Navigator::RenderMainPannelVimix() // cancel tooltip and mouse over on mouse exit if ( !ImGui::IsItemHovered()) { _tooltip = false; - _over = 0; + _displayed_over = _over = 0; } pos_bot = ImGui::GetCursorPos(); @@ -3556,7 +3557,7 @@ void Navigator::RenderMainPannel() /// SOURCE PREVIEW /// -SourcePreview::SourcePreview() : source_(nullptr), label_("") +SourcePreview::SourcePreview() : source_(nullptr), label_(""), pre_frames_(0) { } @@ -3568,6 +3569,7 @@ void SourcePreview::setSource(Source *s, const string &label) source_ = s; label_ = label; + pre_frames_ = 2; } Source * SourcePreview::getSource() @@ -3591,11 +3593,20 @@ void SourcePreview::Render(float width, bool controlbutton) } else { - bool active = source_->active(); - // update source - source_->update( Mixer::manager().dt()); // render framebuffer - source_->render(); + if ( pre_frames_ > 0 && source_->ready() ) { + // trick to ensure a minimum of 2 frames are rendered actively + source_->setActive(true); + source_->update( Mixer::manager().dt() ); + source_->render(); + source_->setActive(false); + --pre_frames_; + } + else { + // update source + source_->update( Mixer::manager().dt() ); + source_->render(); + } // draw preview FrameBuffer *frame = source_->frame(); @@ -3605,14 +3616,18 @@ void SourcePreview::Render(float width, bool controlbutton) if (controlbutton && source_->ready()) { ImVec2 pos = ImGui::GetCursorPos(); ImGui::SameLine(); + bool active = source_->active(); if (ImGuiToolkit::IconToggle(12,7,1,8, &active)) source_->setActive(active); ImGui::SetCursorPos(pos); } ImGuiToolkit::Icon(source_->icon().x, source_->icon().y); ImGui::SameLine(0, 10); - ImGui::Text("%s ", label_.c_str()); - ImGui::Text("%d x %d %s", frame->width(), frame->height(), frame->use_alpha() ? "RGBA" : "RGB"); + ImGui::Text("%s", label_.c_str()); + if (source_->ready()) + ImGui::Text("%d x %d %s", frame->width(), frame->height(), frame->use_alpha() ? "RGBA" : "RGB"); + else + ImGui::Text("loading..."); } } } diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index f18e41e..12d383a 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -19,6 +19,7 @@ class SourcePreview { Source *source_; std::string label_; + int pre_frames_; public: SourcePreview();