From e1e54bbaf38396ee28ff3fca2a9b4625b396e013 Mon Sep 17 00:00:00 2001 From: brunoherbelin Date: Sun, 5 Jul 2020 15:45:52 +0200 Subject: [PATCH] Session transition robust to user manipulation. New pannel to configure parameters of transition. --- Mixer.cpp | 36 +++++++++++++---------- Mixer.h | 3 +- SessionSource.cpp | 4 +-- Settings.cpp | 4 ++- UserInterfaceManager.cpp | 62 ++++++++++++++++++++++++++++------------ UserInterfaceManager.h | 5 ++-- View.cpp | 53 ++++++++++++++++++++++++++++++++-- View.h | 6 ++++ defines.h | 3 +- 9 files changed, 132 insertions(+), 44 deletions(-) diff --git a/Mixer.cpp b/Mixer.cpp index 532ac46..310844f 100644 --- a/Mixer.cpp +++ b/Mixer.cpp @@ -146,7 +146,7 @@ static void saveSession(const std::string& filename, Session *session) } Mixer::Mixer() : session_(nullptr), back_session_(nullptr), current_view_(nullptr), - transition_source_(nullptr), update_time_(GST_CLOCK_TIME_NONE), dt_(0.f) + update_time_(GST_CLOCK_TIME_NONE), dt_(0.f) { // unsused initial empty session session_ = new Session; @@ -364,6 +364,14 @@ void Mixer::deleteSource(Source *s) // log Log::Notify("Source %s deleted.", name.c_str()); } + + // cancel transition source in TRANSITION view + if ( current_view_ == &transition_ ) { + // cancel attachment + transition_.attach(nullptr); + // revert to mixing view + setView(View::MIXING); + } } @@ -517,14 +525,10 @@ Source *Mixer::currentSource() void Mixer::setView(View::Mode m) { // special case when leaving transition view - if ( current_view_ == &transition_ && transition_source_ != nullptr) { - // test if the icon of the transition source is registered for accepting - // this session as current - if (transition_source_->group(View::TRANSITION)->translation_.x > 0.f) - // yes, make this session source the current session - set( transition_source_->detach() ); - // done with transition - transition_source_ = nullptr; + if ( current_view_ == &transition_ ) { + // get the session detached from the transition view and set it as current session + // NB: detatch() can return nullptr, which is then ignored. + set ( transition_.detach() ); } switch (m) { @@ -596,14 +600,16 @@ void Mixer::open(const std::string& filename) if (Settings::application.smooth_transition) { // create special SessionSource to be used for the smooth transition - transition_source_ = new SessionSource(); - transition_source_->load(filename); - - // add the TRANSITION group of the SessionSource to the transition view - transition_.scene.ws()->attach(transition_source_->group(View::TRANSITION)); + SessionSource *ts = new SessionSource(); + ts->load(filename); + // propose a new name based on uri + renameSource(ts, SystemToolkit::base_filename(filename)); // insert source and switch to transition view - insertSource(transition_source_, View::TRANSITION); + insertSource(ts, View::TRANSITION); + + // attach the SessionSource to the transition view + transition_.attach(ts); } else load(filename); diff --git a/Mixer.h b/Mixer.h index d17da2d..9884b28 100644 --- a/Mixer.h +++ b/Mixer.h @@ -92,9 +92,8 @@ protected: MixingView mixing_; GeometryView geometry_; LayerView layer_; - TransitionView transition_; - class SessionSource *transition_source_; +// class SessionSource *transition_source_; gint64 update_time_; float dt_; diff --git a/SessionSource.cpp b/SessionSource.cpp index 5b35dc3..5b87b5e 100644 --- a/SessionSource.cpp +++ b/SessionSource.cpp @@ -53,9 +53,9 @@ SessionSource::SessionSource() : Source(), path_("") frames_[View::TRANSITION]->attach(frame); frame = new Frame(Frame::ROUND, Frame::LARGE, Frame::DROP); frame->translation_.z = 0.01; - frame->color = glm::vec4( COLOR_HIGHLIGHT_SOURCE, 1.f); + frame->color = glm::vec4( COLOR_TRANSITION_SOURCE, 1.f); frames_[View::TRANSITION]->attach(frame); - groups_[View::TRANSITION]->attach(frames_[View::MIXING]); + groups_[View::TRANSITION]->attach(frames_[View::TRANSITION]); overlays_[View::TRANSITION] = new Group; diff --git a/Settings.cpp b/Settings.cpp index 471e810..92ed544 100644 --- a/Settings.cpp +++ b/Settings.cpp @@ -80,7 +80,9 @@ void Settings::Save() // bloc views { XMLElement *viewsNode = xmlDoc.NewElement( "Views" ); - viewsNode->SetAttribute("current", application.current_view); + // save current view only if [mixing, geometry or layers] + int v = application.current_view > 3 ? 1 : application.current_view; + viewsNode->SetAttribute("current", v); viewsNode->SetAttribute("render_view_ar", application.render_view_ar); viewsNode->SetAttribute("render_view_h", application.render_view_h); diff --git a/UserInterfaceManager.cpp b/UserInterfaceManager.cpp index 947b57d..43276e0 100644 --- a/UserInterfaceManager.cpp +++ b/UserInterfaceManager.cpp @@ -294,6 +294,8 @@ void UserInterface::handleKeyboard() Mixer::manager().setView(View::GEOMETRY); else if (ImGui::IsKeyPressed( GLFW_KEY_F3 )) Mixer::manager().setView(View::LAYER); + else if (ImGui::IsKeyPressed( GLFW_KEY_F4 )) // TODO REMOVE (DEBUG ONLY) + Mixer::manager().setView(View::TRANSITION); else if (ImGui::IsKeyPressed( GLFW_KEY_F11 )) Rendering::manager().mainWindow().toggleFullscreen(); else if (ImGui::IsKeyPressed( GLFW_KEY_F12 )) @@ -361,16 +363,6 @@ void UserInterface::handleMouse() if ( !ImGui::IsAnyWindowHovered() && !ImGui::IsAnyWindowFocused() ) { -// if (current) -// { -// glm::vec3 point = Rendering::manager().unProject(mousepos); -// PickingVisitor over(point); -// Mixer::manager().currentView()->scene.accept(over); -// // drag current source -// int c = Mixer::manager().currentView()->over(mousepos, current, over.picked().back()); -// ImGui::SetMouseCursor(c); -// } - // // Mouse wheel over background // @@ -449,7 +441,6 @@ void UserInterface::handleMouse() // indicate to view that an action can be initiated (e.g. grab) Mixer::manager().view()->initiate(); } - } } } @@ -1194,14 +1185,15 @@ void Navigator::Render() ImGui::SetNextWindowBgAlpha(0.95f); // Transparent background if (ImGui::Begin("##navigator", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) { - // the "=" icon for menu - if (ImGui::Selectable( ICON_FA_BARS, &selected_button[NAV_MENU], 0, iconsize)) - { - // Mixer::manager().unsetCurrentSource(); - applyButtonSelection(NAV_MENU); - } if (Settings::application.current_view < 4) { + // the "=" icon for menu + if (ImGui::Selectable( ICON_FA_BARS, &selected_button[NAV_MENU], 0, iconsize)) + { + // Mixer::manager().unsetCurrentSource(); + applyButtonSelection(NAV_MENU); + } + // the list of INITIALS for sources int index = 0; SourceList::iterator iter; @@ -1236,6 +1228,14 @@ void Navigator::Render() } } + else { + // the "=" icon for menu + if (ImGui::Selectable( ICON_FA_BARS, &selected_button[NAV_TRANS], 0, iconsize)) + { + // Mixer::manager().unsetCurrentSource(); + applyButtonSelection(NAV_TRANS); + } + } } ImGui::End(); @@ -1273,6 +1273,11 @@ void Navigator::Render() { RenderMainPannel(); } + // pannel to manage transition + else if (selected_button[NAV_TRANS]) + { + RenderTransitionPannel(); + } // pannel to create a source else if (selected_button[NAV_NEW]) { @@ -1490,6 +1495,25 @@ void Navigator::RenderNewPannel() } +void Navigator::RenderTransitionPannel() +{ + // Next window is a side pannel + ImGui::SetNextWindowPos( ImVec2(width_, 0), ImGuiCond_Always ); + ImGui::SetNextWindowSize( ImVec2(pannel_width_, height_), ImGuiCond_Always ); + ImGui::SetNextWindowBgAlpha(0.85f); // Transparent background + if (ImGui::Begin("##navigatorTrans", NULL, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) + { + // TITLE + ImGui::SetCursorPosY(10); + ImGuiToolkit::PushFont(ImGuiToolkit::FONT_LARGE); + ImGui::Text("Transition"); + ImGui::PopFont(); + + + } + ImGui::End(); +} + void Navigator::RenderMainPannel() { // Next window is a side pannel @@ -1670,6 +1694,7 @@ void Navigator::RenderMainPannel() } // Continue Main pannel + // WINDOWS ImGui::Text(" "); ImGui::Text("Windows"); ImGuiToolkit::ButtonSwitch( IMGUI_TITLE_PREVIEW, &Settings::application.widget.preview, CTRL_MOD "P"); @@ -1681,6 +1706,7 @@ void Navigator::RenderMainPannel() ImGuiToolkit::ButtonSwitch( ICON_FA_LIST " Logs", &Settings::application.widget.logs, CTRL_MOD "L"); ImGuiToolkit::ButtonSwitch( ICON_FA_TACHOMETER_ALT " Metrics", &Settings::application.widget.stats); + // Settings application appearance ImGui::Text(" "); ImGui::Text("Appearance"); ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); @@ -1691,7 +1717,7 @@ void Navigator::RenderMainPannel() if ( ImGui::Combo("Accent", &Settings::application.accent_color, "Blue\0Orange\0Grey\0\0")) ImGuiToolkit::SetAccentColor(static_cast(Settings::application.accent_color)); - // Bottom aligned Logo + // Bottom aligned Logo & About static unsigned int vimixicon = Resource::getTextureImage("images/vimix_256x256.png"); static float h = 4.f * ImGui::GetTextLineHeightWithSpacing(); if ( ImGui::GetCursorPosY() + h + 128.f < height_ ) { diff --git a/UserInterfaceManager.h b/UserInterfaceManager.h index 90e2b8f..4f4f042 100644 --- a/UserInterfaceManager.h +++ b/UserInterfaceManager.h @@ -5,10 +5,11 @@ #include using namespace std; -#define NAV_COUNT 67 +#define NAV_COUNT 68 #define NAV_MAX 64 #define NAV_NEW 65 #define NAV_MENU 66 +#define NAV_TRANS 67 struct ImVec2; class Source; @@ -46,7 +47,7 @@ class Navigator // side pannels void RenderSourcePannel(Source *s); void RenderMainPannel(); - + void RenderTransitionPannel(); void RenderNewPannel(); int new_source_type_; char file_browser_path_[2048]; diff --git a/View.cpp b/View.cpp index a1f061a..467eebd 100644 --- a/View.cpp +++ b/View.cpp @@ -12,7 +12,9 @@ #include "defines.h" #include "Settings.h" #include "View.h" +#include "Session.h" #include "Source.h" +#include "SessionSource.h" #include "Primitives.h" #include "Decorations.h" #include "PickingVisitor.h" @@ -155,6 +157,8 @@ MixingView::MixingView() : View(MIXING), limbo_scale_(1.3f) scene.root()->translation_ = glm::vec3(1.0f, 0.0f, 0.0f); saveSettings(); } + else + restoreSettings(); // Mixing scene background Mesh *disk = new Mesh("mesh/disk.ply"); @@ -334,6 +338,8 @@ GeometryView::GeometryView() : View(GEOMETRY) scene.root()->scale_ = glm::vec3(GEOMETRY_DEFAULT_SCALE, GEOMETRY_DEFAULT_SCALE, 1.0f); saveSettings(); } + else + restoreSettings(); // Geometry Scene background Surface *rect = new Surface; @@ -578,6 +584,8 @@ LayerView::LayerView() : View(LAYER), aspect_ratio(1.f) scene.root()->translation_ = glm::vec3(1.3f, 1.f, 0.0f); saveSettings(); } + else + restoreSettings(); // Geometry Scene background Surface *rect = new Surface; @@ -681,10 +689,10 @@ View::Cursor LayerView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::pair // TRANSITION -TransitionView::TransitionView() : View(TRANSITION), duration_(1000.f) +TransitionView::TransitionView() : View(TRANSITION), duration_(1000.f), transition_source_(nullptr) { // read default settings - //if ( Settings::application.views[mode_].name.empty() ) + if ( Settings::application.views[mode_].name.empty() ) { // no settings found: store application default Settings::application.views[mode_].name = "Transition"; @@ -692,6 +700,8 @@ TransitionView::TransitionView() : View(TRANSITION), duration_(1000.f) scene.root()->translation_ = glm::vec3(1.8f, 0.f, 0.0f); saveSettings(); } + else + restoreSettings(); // Geometry Scene background Mesh *circle = new Mesh("mesh/h_line.ply"); @@ -732,6 +742,43 @@ void TransitionView::update(float dt) } + +void TransitionView::attach(SessionSource *ts) +{ + // store source for later (detatch & interaction) + transition_source_ = ts; + + if ( transition_source_ != nullptr) { + // insert in scene + Group *tg = transition_source_->group(View::TRANSITION); + tg->visible_ = true; + scene.ws()->attach(tg); + } +} + +Session *TransitionView::detach() +{ + // by default, nothing to return + Session *ret = nullptr; + + if ( transition_source_ != nullptr) { + + // get and detatch the group node from the view workspace + Group *tg = transition_source_->group(View::TRANSITION); + scene.ws()->detatch( tg ); + + // test if the icon of the transition source is "Ready" + if ( tg->translation_.x > 0.f ) + // detatch the session and return it + ret = transition_source_->detach(); + + // done with transition + transition_source_ = nullptr; + } + + return ret; +} + //void TransitionView::draw() //{ // // draw scene of this view @@ -752,7 +799,7 @@ void TransitionView::zoom (float factor) void TransitionView::centerSource(Source *s) { - // setup view so that the center of the source is accessible + // TODO setup view when starting : anything to initialize ? } diff --git a/View.h b/View.h index c99a0c2..2d7741c 100644 --- a/View.h +++ b/View.h @@ -6,6 +6,7 @@ #include "Scene.h" #include "FrameBuffer.h" class Source; +class SessionSource; class View { @@ -148,6 +149,10 @@ class TransitionView : public View public: TransitionView(); + void attach(SessionSource *ts); + class Session *detach(); + inline SessionSource * attached() { return transition_source_; } + void centerSource(Source *) override; void update (float dt) override; void zoom (float factor) override; @@ -156,6 +161,7 @@ public: private: float duration_; class Surface *output_surface_; + SessionSource *transition_source_; }; diff --git a/defines.h b/defines.h index 1d1afd0..0f7c5fa 100644 --- a/defines.h +++ b/defines.h @@ -56,8 +56,9 @@ #define COLOR_BGROUND 0.2f, 0.2f, 0.2f #define COLOR_NAVIGATOR 0.1f, 0.1f, 0.1f #define COLOR_DEFAULT_SOURCE 0.8f, 0.8f, 0.8f -#define COLOR_TRANSITION_LINES 0.9f, 0.9f, 0.9f #define COLOR_HIGHLIGHT_SOURCE 1.f, 1.f, 1.f +#define COLOR_TRANSITION_SOURCE 1.f, 0.5f, 1.f +#define COLOR_TRANSITION_LINES 0.9f, 0.9f, 0.9f #define COLOR_FRAME 0.8f, 0.f, 0.8f #define COLOR_LIMBO_CIRCLE 0.16f, 0.16f, 0.16f