From 5b489dd2df131c286019d1a9a5b8e8f27cab5823 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Thu, 21 May 2020 14:12:36 +0200 Subject: [PATCH] Bugfix MediaPlayer, ButtonOpenUrl and UserInterfaceManager --- ImGuiToolkit.cpp | 21 ++----- ImGuiToolkit.h | 2 +- ImGuiVisitor.cpp | 3 + MediaPlayer.cpp | 9 +-- MediaPlayer.h | 2 +- Source.cpp | 2 +- SystemToolkit.cpp | 15 +++++ SystemToolkit.h | 2 + UserInterfaceManager.cpp | 119 ++++++++++++++++++++++----------------- main.cpp | 5 +- 10 files changed, 102 insertions(+), 78 deletions(-) diff --git a/ImGuiToolkit.cpp b/ImGuiToolkit.cpp index c61f0cb..6a8dccb 100644 --- a/ImGuiToolkit.cpp +++ b/ImGuiToolkit.cpp @@ -21,32 +21,19 @@ #include "FileDialog.h" #include "ImGuiToolkit.h" #include "GstToolkit.h" +#include "SystemToolkit.h" unsigned int textureicons = 0; std::map fontmap; -void ImGuiToolkit::ButtonOpenWebpage( const char* url ) +void ImGuiToolkit::ButtonOpenUrl( const char* url, const ImVec2& size_arg ) { char label[512]; sprintf( label, "%s %s", ICON_FA_EXTERNAL_LINK_ALT, url ); - if ( ImGui::Button(label) ) - { - -#ifdef _WIN32 - ShellExecuteA( nullptr, nullptr, url, nullptr, nullptr, 0 ); -#elif defined __APPLE__ - char buf[1024]; - sprintf( buf, "open %s", url ); - system( buf ); -#else - char buf[1024]; - sprintf( buf, "xdg-open %s", url ); - system( buf ); -#endif - - } + if ( ImGui::Button(label, size_arg) ) + SystemToolkit::open(url); } diff --git a/ImGuiToolkit.h b/ImGuiToolkit.h index fe4076d..f40681c 100644 --- a/ImGuiToolkit.h +++ b/ImGuiToolkit.h @@ -21,7 +21,7 @@ namespace ImGuiToolkit bool ButtonIconMultistate(std::vector > icons, int* state); void ButtonToggle( const char* label, bool* toggle ); void ButtonSwitch(const char* label, bool* toggle , const char *help = nullptr); - void ButtonOpenWebpage( const char* url ); + void ButtonOpenUrl( const char* url, const ImVec2& size_arg = ImVec2(0,0)); void HelpMarker(const char* desc); diff --git a/ImGuiVisitor.cpp b/ImGuiVisitor.cpp index c8dff55..a1371bf 100644 --- a/ImGuiVisitor.cpp +++ b/ImGuiVisitor.cpp @@ -21,6 +21,7 @@ #include "imgui.h" #include "ImGuiToolkit.h" +#include "SystemToolkit.h" ImGuiVisitor::ImGuiVisitor() @@ -278,6 +279,7 @@ void ImGuiVisitor::visit (MediaSource& s) if (ImGui::Button("Open Media Player", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) Settings::application.media_player = true; } + ImGuiToolkit::ButtonOpenUrl( SystemToolkit::path_filename(s.path()).c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) ); } void ImGuiVisitor::visit (SessionSource& s) @@ -286,4 +288,5 @@ void ImGuiVisitor::visit (SessionSource& s) ImGui::Text("Session"); if (ImGui::Button("Make Current", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) Mixer::manager().set( s.detach() ); + ImGuiToolkit::ButtonOpenUrl( SystemToolkit::path_filename(s.path()).c_str(), ImVec2(IMGUI_RIGHT_ALIGN, 0) ); } diff --git a/MediaPlayer.cpp b/MediaPlayer.cpp index dadeae0..e057456 100644 --- a/MediaPlayer.cpp +++ b/MediaPlayer.cpp @@ -610,7 +610,7 @@ double MediaPlayer::updateFrameRate() const // CALLBACKS -bool MediaPlayer::fill_v_frame(GstBuffer *buf) +bool MediaPlayer::fill_v_frame(GstBuffer *buf, bool ignorepts) { // always empty frame before filling it again if (v_frame_.buffer) @@ -618,7 +618,7 @@ bool MediaPlayer::fill_v_frame(GstBuffer *buf) // get the frame from buffer if ( !gst_video_frame_map (&v_frame_, &v_frame_video_info_, buf, GST_MAP_READ ) ) { - Log::Info("MediaPlayer %s Failed to map the video buffer"); + Log::Info("MediaPlayer %s Failed to map the video buffer", id_.c_str()); return false; } @@ -626,7 +626,8 @@ bool MediaPlayer::fill_v_frame(GstBuffer *buf) if( GST_VIDEO_INFO_IS_RGB(&(v_frame_).info) && GST_VIDEO_INFO_N_PLANES(&(v_frame_).info) == 1) { // validate time - if (position_ != buf->pts) { + if (ignorepts || position_ != buf->pts) + { // got a new RGB frame ! v_frame_is_full_ = true; @@ -664,7 +665,7 @@ GstFlowReturn MediaPlayer::callback_pull_sample_video (GstElement *bin, MediaPla GstBuffer *buf = gst_buffer_ref ( gst_sample_get_buffer (sample) ); // fill frame from buffer - if ( !m->fill_v_frame(buf) ) + if ( !m->fill_v_frame(buf, m->isimage_) ) ret = GST_FLOW_ERROR; // free buffer gst_buffer_unref (buf); diff --git a/MediaPlayer.h b/MediaPlayer.h index b3b6751..dac5bda 100644 --- a/MediaPlayer.h +++ b/MediaPlayer.h @@ -255,7 +255,7 @@ private: void execute_open(); void execute_loop_command(); void execute_seek_command(GstClockTime target = GST_CLOCK_TIME_NONE); - bool fill_v_frame(GstBuffer *buf); + bool fill_v_frame(GstBuffer *buf, bool ignorepts = false); static GstFlowReturn callback_pull_sample_video (GstElement *bin, MediaPlayer *m); static void callback_end_of_video (GstElement *, MediaPlayer *m); diff --git a/Source.cpp b/Source.cpp index 9d935ca..983b5a0 100644 --- a/Source.cpp +++ b/Source.cpp @@ -143,7 +143,7 @@ void Source::update(float dt) // ADJUST alpha based on MIXING node // read position of the mixing node and interpret this as transparency of render output glm::vec2 dist = glm::vec2(groups_[View::MIXING]->translation_); - float alpha = 1.0 - CLAMP( SQUARE( glm::length(dist) ), 0.f, 1.f ); + float alpha = 1.0 - CLAMP( ( dist.x * dist.x ) + ( dist.y * dist.y ), 0.f, 1.f ); blendingshader_->color.a = alpha; // MODIFY geometry based on GEOMETRY node diff --git a/SystemToolkit.cpp b/SystemToolkit.cpp index b32c059..8e4a4ea 100644 --- a/SystemToolkit.cpp +++ b/SystemToolkit.cpp @@ -146,3 +146,18 @@ bool SystemToolkit::create_directory(const string& path) // TODO : verify WIN32 implementation } + +void SystemToolkit::open(const std::string& url) +{ +#ifdef WIN32 + ShellExecuteA( nullptr, nullptr, url.c_str(), nullptr, nullptr, 0 ); +#elif defined APPLE + char buf[2048]; + sprintf( buf, "open '%s'", url.c_str() ); + system( buf ); +#else + char buf[2048]; + sprintf( buf, "xdg-open '%s'", url.c_str() ); + system( buf ); +#endif +} diff --git a/SystemToolkit.h b/SystemToolkit.h index c2a156a..8ccc3a1 100644 --- a/SystemToolkit.h +++ b/SystemToolkit.h @@ -39,6 +39,8 @@ namespace SystemToolkit // true if directory could be created bool create_directory(const std::string& path); + // try to open the file with system + void open(const std::string& path); } #endif // SYSTEMTOOLKIT_H diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 2e46064..123af5c 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -58,15 +58,15 @@ void ShowAboutOpengl(bool* p_open); void ShowAbout(bool* p_open); // static objects for multithreaded file dialog -static std::atomic FileDialogPending_ = false; -static std::atomic SessionFileDialogLoadFinished_ = false; -static std::atomic SessionFileDialogSaveFinished_ = false; -static std::string SessionFileDialogFilename_ = ""; +static std::atomic fileDialogPending_ = false; +static std::atomic sessionFileDialogLoadFinished_ = false; +static std::atomic sessionFileDialogSaveFinished_ = false; +static std::string sessionFileDialogFilename_ = ""; static void SessionFileDialogOpen(std::string path) { - FileDialogPending_ = true; - SessionFileDialogLoadFinished_ = false; + fileDialogPending_ = true; + sessionFileDialogLoadFinished_ = false; char const * open_file_name; char const * open_pattern[1] = { "*.vmx" }; @@ -74,17 +74,17 @@ static void SessionFileDialogOpen(std::string path) open_file_name = tinyfd_openFileDialog( "Open a session file", path.c_str(), 1, open_pattern, "vimix session", 0); if (!open_file_name) - SessionFileDialogFilename_ = ""; + sessionFileDialogFilename_ = ""; else - SessionFileDialogFilename_ = std::string( open_file_name ); + sessionFileDialogFilename_ = std::string( open_file_name ); - SessionFileDialogLoadFinished_ = true; + sessionFileDialogLoadFinished_ = true; } static void SessionFileDialogSave(std::string path) { - FileDialogPending_ = true; - SessionFileDialogSaveFinished_ = false; + fileDialogPending_ = true; + sessionFileDialogSaveFinished_ = false; char const * save_file_name; char const * save_pattern[1] = { "*.vmx" }; @@ -92,32 +92,32 @@ static void SessionFileDialogSave(std::string path) save_file_name = tinyfd_saveFileDialog( "Save a session file", path.c_str(), 1, save_pattern, "vimix session"); if (!save_file_name) - SessionFileDialogFilename_ = ""; + sessionFileDialogFilename_ = ""; else { - SessionFileDialogFilename_ = std::string( save_file_name ); + sessionFileDialogFilename_ = std::string( save_file_name ); // check extension - std::string extension = SessionFileDialogFilename_.substr(SessionFileDialogFilename_.find_last_of(".") + 1); + std::string extension = sessionFileDialogFilename_.substr(sessionFileDialogFilename_.find_last_of(".") + 1); if (extension != "vmx") - SessionFileDialogFilename_ += ".vmx"; + sessionFileDialogFilename_ += ".vmx"; } - SessionFileDialogSaveFinished_ = true; + sessionFileDialogSaveFinished_ = true; } static void ImportFileDialogOpen(char *filename, const std::string &path) { - if (FileDialogPending_) + if (fileDialogPending_) return; - FileDialogPending_ = true; + fileDialogPending_ = true; - char const * open_pattern[17] = { "*vmx", "*.mp4", "*.mpg", "*.avi", "*.mov", "*.mkv", "*.webm", "*.mod", "*.wmv", "*.mxf", "*.ogg", "*.flv", "*.asf", "*.jpg", "*.png", "*.gif", "*.svg" }; + char const * open_pattern[18] = { "*vmx", "*.mp4", "*.mpg", "*.avi", "*.mov", "*.mkv", "*.webm", "*.mod", "*.wmv", "*.mxf", "*.ogg", "*.flv", "*.asf", "*.jpg", "*.png", "*.gif", "*.tif", "*.svg" }; char const * open_file_name; - open_file_name = tinyfd_openFileDialog( "Import a file", path.c_str(), 17, open_pattern, "All supported formats", 0); + open_file_name = tinyfd_openFileDialog( "Import a file", path.c_str(), 18, open_pattern, "All supported formats", 0); sprintf(filename, "%s", open_file_name); - FileDialogPending_ = false; + fileDialogPending_ = false; } UserInterface::UserInterface() @@ -239,17 +239,12 @@ void UserInterface::handleKeyboard() } } + // No CTRL modifier else { - // TODO make sure no entry / window box is active keyboard_modifier_active = false; - // Action keys - if (ImGui::IsKeyPressed( GLFW_KEY_BACKSPACE )) - Mixer::manager().deleteCurrentSource(); - else if (ImGui::IsKeyPressed( GLFW_KEY_GRAVE_ACCENT )) - navigator.toggleMenu(); // Application F-Keys - else if (ImGui::IsKeyPressed( GLFW_KEY_F1 )) + if (ImGui::IsKeyPressed( GLFW_KEY_F1 )) Mixer::manager().setCurrentView(View::MIXING); else if (ImGui::IsKeyPressed( GLFW_KEY_F2 )) Mixer::manager().setCurrentView(View::GEOMETRY); @@ -257,12 +252,22 @@ void UserInterface::handleKeyboard() Mixer::manager().setCurrentView(View::LAYER); else if (ImGui::IsKeyPressed( GLFW_KEY_F11 )) Rendering::manager().ToggleFullscreen(); - else if (ImGui::IsKeyPressed( GLFW_KEY_ESCAPE )){ - if (Rendering::manager().IsFullscreen()) - Rendering::manager().ToggleFullscreen(); - } else if (ImGui::IsKeyPressed( GLFW_KEY_F12 )) toolbox.StartScreenshot(); + // normal keys // make sure no entry / window box is active + else if ( !ImGui::IsAnyWindowFocused() ){ + // Backspace to delete source + if (ImGui::IsKeyPressed( GLFW_KEY_BACKSPACE )) + Mixer::manager().deleteCurrentSource(); + // button under esc to toggle menu + else if (ImGui::IsKeyPressed( GLFW_KEY_GRAVE_ACCENT )) + navigator.toggleMenu(); + // esc to exit fullscreen + else if (ImGui::IsKeyPressed( GLFW_KEY_ESCAPE )){ + if (Rendering::manager().IsFullscreen()) + Rendering::manager().ToggleFullscreen(); + } + } } } @@ -327,10 +332,13 @@ void UserInterface::handleMouse() else { // Log::Info("Mouse drag (%.1f,%.1f)(%.1f,%.1f)", io.MouseClickedPos[0].x, io.MouseClickedPos[0].y, io.MousePos.x, io.MousePos.y); // Selection area - ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, - ImGui::GetColorU32(ImGuiCol_ResizeGripHovered)); - ImGui::GetBackgroundDrawList()->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, - ImGui::GetColorU32(ImGuiCol_ResizeGripHovered, 0.3f)); +// ImGui::GetBackgroundDrawList()->AddRect(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, +// ImGui::GetColorU32(ImGuiCol_ResizeGripHovered)); +// ImGui::GetBackgroundDrawList()->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, +// ImGui::GetColorU32(ImGuiCol_ResizeGripHovered, 0.3f)); + +// TODO Multiple sources selection + } } else if ( ImGui::IsMouseDown(ImGuiMouseButton_Left) ) { @@ -378,25 +386,25 @@ void UserInterface::NewFrame() handleMouse(); // handle FileDialog - if (SessionFileDialogLoadFinished_) { - SessionFileDialogLoadFinished_ = false; - FileDialogPending_ = false; - if (!SessionFileDialogFilename_.empty()) { - Mixer::manager().open(SessionFileDialogFilename_); - Settings::application.recentSessions.path = SystemToolkit::path_filename(SessionFileDialogFilename_); + if (sessionFileDialogLoadFinished_) { + sessionFileDialogLoadFinished_ = false; + fileDialogPending_ = false; + if (!sessionFileDialogFilename_.empty()) { + Mixer::manager().open(sessionFileDialogFilename_); + Settings::application.recentSessions.path = SystemToolkit::path_filename(sessionFileDialogFilename_); } } - if (SessionFileDialogSaveFinished_) { - SessionFileDialogSaveFinished_ = false; - FileDialogPending_ = false; - if (!SessionFileDialogFilename_.empty()) { - Mixer::manager().saveas(SessionFileDialogFilename_); - Settings::application.recentSessions.path = SystemToolkit::path_filename(SessionFileDialogFilename_); + if (sessionFileDialogSaveFinished_) { + sessionFileDialogSaveFinished_ = false; + fileDialogPending_ = false; + if (!sessionFileDialogFilename_.empty()) { + Mixer::manager().saveas(sessionFileDialogFilename_); + Settings::application.recentSessions.path = SystemToolkit::path_filename(sessionFileDialogFilename_); } } // overlay to ensure file dialog is modal - if (FileDialogPending_){ + if (fileDialogPending_){ ImGui::OpenPopup("Busy"); if (ImGui::BeginPopupModal("Busy", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { @@ -913,6 +921,7 @@ void Navigator::Render() // the "=" icon for menu if (ImGui::Selectable( ICON_FA_BARS, &selected_button[NAV_MENU], 0, iconsize)) { + Mixer::manager().unsetCurrentSource(); toggle(NAV_MENU); } // the list of INITIALS for sources @@ -984,7 +993,11 @@ void Navigator::Render() // window menu if (selected_button[NAV_MENU]) { - RenderMainPannel(); + // if a source is selected in the meantime, revert to selected source pannel + if (Mixer::manager().indexCurrentSource() > -1 ) + selected_button[NAV_MENU] = false; + else + RenderMainPannel(); } // window to create a source else if (selected_button[NAV_NEW]) @@ -1234,7 +1247,7 @@ void ShowAbout(bool* p_open) ImGui::Separator(); ImGui::Text("vimix is a video mixing software for live performance."); ImGui::Text("vimix is licensed under the GNU GPL version 3. Copyright 2019-2020 Bruno Herbelin."); - ImGuiToolkit::ButtonOpenWebpage("https://github.com/brunoherbelin/v-mix"); + ImGuiToolkit::ButtonOpenUrl("https://github.com/brunoherbelin/v-mix"); ImGui::End(); } @@ -1253,7 +1266,7 @@ void ShowAboutOpengl(bool* p_open) ImGui::PopFont(); ImGui::Separator(); ImGui::Text("OpenGL is the premier environment for developing portable, \ninteractive 2D and 3D graphics applications."); - ImGuiToolkit::ButtonOpenWebpage("https://www.opengl.org"); + ImGuiToolkit::ButtonOpenUrl("https://www.opengl.org"); ImGui::SameLine(); static bool show_opengl_info = false; @@ -1320,7 +1333,7 @@ void ShowAboutGStreamer(bool* p_open) ImGui::Separator(); ImGui::Text("A flexible, fast and multiplatform multimedia framework."); ImGui::Text("GStreamer is licensed under the LGPL License."); - ImGuiToolkit::ButtonOpenWebpage("https://gstreamer.freedesktop.org/"); + ImGuiToolkit::ButtonOpenUrl("https://gstreamer.freedesktop.org/"); ImGui::SameLine(); static bool show_config_info = false; diff --git a/main.cpp b/main.cpp index aa5086b..68252aa 100644 --- a/main.cpp +++ b/main.cpp @@ -75,8 +75,11 @@ int main(int, char**) /// GStreamer /// #ifndef NDEBUG - gst_debug_set_default_threshold (GST_LEVEL_ERROR); + gst_debug_set_default_threshold (GST_LEVEL_WARNING); gst_debug_set_active(TRUE); +#else + gst_debug_set_default_threshold (GST_LEVEL_ERROR); + gst_debug_set_active(FALSE); #endif // test text editor