mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-05 23:40:02 +01:00
Convert Snapshots into Versions of session
Added auto-snapshot on save to have an Iterative Saving mode, and change terminology of 'snapshots' to 'versions' management.
This commit is contained in:
@@ -202,7 +202,7 @@ void Action::restore(uint target)
|
||||
|
||||
|
||||
|
||||
void Action::snapshot(const std::string &label)
|
||||
void Action::snapshot(const std::string &label, bool threaded)
|
||||
{
|
||||
// ignore if locked
|
||||
if (locked_)
|
||||
@@ -217,8 +217,11 @@ void Action::snapshot(const std::string &label)
|
||||
Session *se = Mixer::manager().session();
|
||||
se->snapshots()->keys_.push_back(id);
|
||||
|
||||
// threaded capture state of current session
|
||||
std::thread(captureMixerSession, se->snapshots()->xmlDoc_, SNAPSHOT_NODE(id), snap_label).detach();
|
||||
if (threaded)
|
||||
// threaded capture state of current session
|
||||
std::thread(captureMixerSession, se->snapshots()->xmlDoc_, SNAPSHOT_NODE(id), snap_label).detach();
|
||||
else
|
||||
captureMixerSession(se->snapshots()->xmlDoc_, SNAPSHOT_NODE(id), snap_label);
|
||||
|
||||
#ifdef ACTION_DEBUG
|
||||
Log::Info("Snapshot stored %d '%s'", id, snap_label.c_str());
|
||||
@@ -321,6 +324,12 @@ FrameBufferImage *Action::thumbnail(uint64_t snapshotid) const
|
||||
return img;
|
||||
}
|
||||
|
||||
void Action::clearSnapshots()
|
||||
{
|
||||
Session *se = Mixer::manager().session();
|
||||
se->snapshots()->keys_.clear();
|
||||
}
|
||||
|
||||
void Action::remove(uint64_t snapshotid)
|
||||
{
|
||||
if (snapshotid > 0)
|
||||
|
||||
@@ -39,8 +39,8 @@ public:
|
||||
FrameBufferImage *thumbnail (uint s) const;
|
||||
|
||||
// Snapshots
|
||||
void snapshot (const std::string &label = "");
|
||||
|
||||
void snapshot (const std::string &label = "", bool threaded = false);
|
||||
void clearSnapshots ();
|
||||
std::list<uint64_t> snapshots () const;
|
||||
uint64_t currentSnapshot () const { return snapshot_id_; }
|
||||
|
||||
|
||||
14
Mixer.cpp
14
Mixer.cpp
@@ -62,8 +62,12 @@ const std::chrono::milliseconds timeout_ = std::chrono::milliseconds(4);
|
||||
|
||||
|
||||
// static multithreaded session saving
|
||||
static void saveSession(const std::string& filename, Session *session)
|
||||
static void saveSession(const std::string& filename, Session *session, bool with_version)
|
||||
{
|
||||
// capture a snapshot of current version if requested
|
||||
if (with_version)
|
||||
Action::manager().snapshot( SystemToolkit::date_time_string());
|
||||
|
||||
// lock access while saving
|
||||
session->lock();
|
||||
|
||||
@@ -971,13 +975,13 @@ View *Mixer::view(View::Mode m)
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::save()
|
||||
void Mixer::save(bool with_version)
|
||||
{
|
||||
if (!session_->filename().empty())
|
||||
saveas(session_->filename());
|
||||
saveas(session_->filename(), with_version);
|
||||
}
|
||||
|
||||
void Mixer::saveas(const std::string& filename)
|
||||
void Mixer::saveas(const std::string& filename, bool with_version)
|
||||
{
|
||||
// optional copy of views config
|
||||
session_->config(View::MIXING)->copyTransform( mixing_.scene.root() );
|
||||
@@ -986,7 +990,7 @@ void Mixer::saveas(const std::string& filename)
|
||||
session_->config(View::TEXTURE)->copyTransform( appearance_.scene.root() );
|
||||
|
||||
// launch a thread to save the session
|
||||
std::thread (saveSession, filename, session_).detach();
|
||||
std::thread (saveSession, filename, session_, with_version).detach();
|
||||
}
|
||||
|
||||
void Mixer::load(const std::string& filename)
|
||||
|
||||
4
Mixer.h
4
Mixer.h
@@ -99,8 +99,8 @@ public:
|
||||
// manipulate, load and save sessions
|
||||
inline Session *session () const { return session_; }
|
||||
void clear ();
|
||||
void save ();
|
||||
void saveas (const std::string& filename);
|
||||
void save (bool with_version = false);
|
||||
void saveas (const std::string& filename, bool with_version = false);
|
||||
void load (const std::string& filename);
|
||||
void import (const std::string& filename);
|
||||
void import (SessionSource *source);
|
||||
|
||||
@@ -85,11 +85,11 @@ void Settings::Save(uint64_t runtime)
|
||||
applicationNode->SetAttribute("scale", application.scale);
|
||||
applicationNode->SetAttribute("accent_color", application.accent_color);
|
||||
applicationNode->SetAttribute("smooth_transition", application.smooth_transition);
|
||||
applicationNode->SetAttribute("smooth_snapshot", application.smooth_snapshot);
|
||||
applicationNode->SetAttribute("save_snapshot", application.save_version_snapshot);
|
||||
applicationNode->SetAttribute("smooth_cursor", application.smooth_cursor);
|
||||
applicationNode->SetAttribute("action_history_follow_view", application.action_history_follow_view);
|
||||
applicationNode->SetAttribute("accept_connections", application.accept_connections);
|
||||
applicationNode->SetAttribute("pannel_history_mode", application.pannel_history_mode);
|
||||
applicationNode->SetAttribute("pannel_history_mode", application.pannel_current_session_mode);
|
||||
pRoot->InsertEndChild(applicationNode);
|
||||
|
||||
// Widgets
|
||||
@@ -312,11 +312,11 @@ void Settings::Load()
|
||||
applicationNode->QueryFloatAttribute("scale", &application.scale);
|
||||
applicationNode->QueryIntAttribute("accent_color", &application.accent_color);
|
||||
applicationNode->QueryBoolAttribute("smooth_transition", &application.smooth_transition);
|
||||
applicationNode->QueryBoolAttribute("smooth_snapshot", &application.smooth_snapshot);
|
||||
applicationNode->QueryBoolAttribute("save_snapshot", &application.save_version_snapshot);
|
||||
applicationNode->QueryBoolAttribute("smooth_cursor", &application.smooth_cursor);
|
||||
applicationNode->QueryBoolAttribute("action_history_follow_view", &application.action_history_follow_view);
|
||||
applicationNode->QueryBoolAttribute("accept_connections", &application.accept_connections);
|
||||
applicationNode->QueryIntAttribute("pannel_history_mode", &application.pannel_history_mode);
|
||||
applicationNode->QueryIntAttribute("pannel_history_mode", &application.pannel_current_session_mode);
|
||||
}
|
||||
|
||||
// Widgets
|
||||
|
||||
@@ -203,12 +203,12 @@ struct Application
|
||||
// Global settings Application interface
|
||||
float scale;
|
||||
int accent_color;
|
||||
bool smooth_snapshot;
|
||||
bool save_version_snapshot;
|
||||
bool smooth_transition;
|
||||
bool smooth_cursor;
|
||||
bool action_history_follow_view;
|
||||
|
||||
int pannel_history_mode;
|
||||
int pannel_current_session_mode;
|
||||
|
||||
// connection settings
|
||||
bool accept_connections;
|
||||
@@ -252,11 +252,11 @@ struct Application
|
||||
scale = 1.f;
|
||||
accent_color = 0;
|
||||
smooth_transition = false;
|
||||
smooth_snapshot = false;
|
||||
save_version_snapshot = false;
|
||||
smooth_cursor = false;
|
||||
action_history_follow_view = false;
|
||||
accept_connections = false;
|
||||
pannel_history_mode = 0;
|
||||
pannel_current_session_mode = 0;
|
||||
current_view = 1;
|
||||
current_workspace= 1;
|
||||
brush = glm::vec3(0.5f, 0.1f, 0.f);
|
||||
|
||||
@@ -249,11 +249,12 @@ void UserInterface::handleKeyboard()
|
||||
selectOpenFilename();
|
||||
}
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_S )) {
|
||||
// Save Session
|
||||
if (shift_modifier_active || Mixer::manager().session()->filename().empty())
|
||||
// SHIFT + CTRL + S : save as
|
||||
if (shift_modifier_active)
|
||||
selectSaveFilename();
|
||||
// CTRL + S : save (save as if necessary)
|
||||
else
|
||||
Mixer::manager().save();
|
||||
saveOrSaveAs();
|
||||
}
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_W )) {
|
||||
// New Session
|
||||
@@ -326,9 +327,6 @@ void UserInterface::handleKeyboard()
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_Y )) {
|
||||
Action::manager().snapshot( "Snap" );
|
||||
}
|
||||
else if (ImGui::IsKeyPressed( GLFW_KEY_Z )) {
|
||||
if (shift_modifier_active)
|
||||
Action::manager().redo();
|
||||
@@ -703,6 +701,20 @@ void UserInterface::handleMouse()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool UserInterface::saveOrSaveAs(bool force_versioning)
|
||||
{
|
||||
bool finished = false;
|
||||
|
||||
if (Mixer::manager().session()->filename().empty())
|
||||
selectSaveFilename();
|
||||
else {
|
||||
Mixer::manager().save(force_versioning || Settings::application.save_version_snapshot);
|
||||
finished = true;
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
|
||||
void UserInterface::selectSaveFilename()
|
||||
{
|
||||
if (sessionsavedialog)
|
||||
@@ -740,7 +752,7 @@ void UserInterface::NewFrame()
|
||||
Mixer::manager().import(sessionimportdialog->path());
|
||||
|
||||
if (sessionsavedialog && sessionsavedialog->closed() && !sessionsavedialog->path().empty())
|
||||
Mixer::manager().saveas(sessionsavedialog->path());
|
||||
Mixer::manager().saveas(sessionsavedialog->path(), Settings::application.save_version_snapshot);
|
||||
|
||||
// overlay to ensure file dialog is modal
|
||||
if (DialogToolkit::FileDialog::busy()){
|
||||
@@ -839,7 +851,7 @@ void UserInterface::Render()
|
||||
void UserInterface::Terminate()
|
||||
{
|
||||
if (Settings::application.recentSessions.save_on_exit)
|
||||
Mixer::manager().save();
|
||||
Mixer::manager().save(false);
|
||||
|
||||
// Cleanup
|
||||
ImGui_ImplOpenGL3_Shutdown();
|
||||
@@ -880,8 +892,6 @@ void UserInterface::showMenuEdit()
|
||||
Action::manager().undo();
|
||||
if ( ImGui::MenuItem( ICON_FA_REDO " Redo", CTRL_MOD "Shift+Z") )
|
||||
Action::manager().redo();
|
||||
if ( ImGui::MenuItem( ICON_FA_STAR "+ Snapshot", CTRL_MOD "Y") )
|
||||
Action::manager().snapshot( "Snap" );
|
||||
}
|
||||
|
||||
void UserInterface::showMenuFile()
|
||||
@@ -910,12 +920,8 @@ void UserInterface::showMenuFile()
|
||||
navigator.hidePannel();
|
||||
}
|
||||
if (ImGui::MenuItem( ICON_FA_FILE_DOWNLOAD " Save", CTRL_MOD "S")) {
|
||||
if (Mixer::manager().session()->filename().empty())
|
||||
selectSaveFilename();
|
||||
else {
|
||||
Mixer::manager().save();
|
||||
if (saveOrSaveAs())
|
||||
navigator.hidePannel();
|
||||
}
|
||||
}
|
||||
if (ImGui::MenuItem( ICON_FA_FILE_DOWNLOAD " Save as", CTRL_MOD "Shift+S"))
|
||||
selectSaveFilename();
|
||||
@@ -4440,7 +4446,6 @@ void Navigator::RenderMainPannelVimix()
|
||||
|
||||
ImVec2 pos_bot = ImGui::GetCursorPos();
|
||||
|
||||
|
||||
// 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 " +" )) {
|
||||
@@ -4464,20 +4469,20 @@ void Navigator::RenderMainPannelVimix()
|
||||
// come back...
|
||||
ImGui::SetCursorPos(pos_bot);
|
||||
|
||||
|
||||
//
|
||||
// Status
|
||||
//
|
||||
ImGuiToolkit::Spacing();
|
||||
ImGui::Text("Current");
|
||||
ImGui::Text("Current session");
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
ImGui::Combo("##SelectHistory", &Settings::application.pannel_history_mode,
|
||||
ICON_FA_STAR " Snapshots\0" ICON_FA_HISTORY " Undo history\0" ICON_FA_FILE_ALT " Properties\0");
|
||||
ImGui::Combo("##Selectpanelsession", &Settings::application.pannel_current_session_mode,
|
||||
ICON_FA_CODE_BRANCH " Versions\0" ICON_FA_HISTORY " Undo history\0" ICON_FA_FILE_ALT " Properties\0");
|
||||
pos_bot = ImGui::GetCursorPos();
|
||||
|
||||
//
|
||||
// Current 2. PROPERTIES
|
||||
//
|
||||
if (Settings::application.pannel_history_mode > 1) {
|
||||
if (Settings::application.pannel_current_session_mode > 1) {
|
||||
|
||||
std::string sessionfilename = Mixer::manager().session()->filename();
|
||||
|
||||
@@ -4583,7 +4588,7 @@ void Navigator::RenderMainPannelVimix()
|
||||
if (_file_thumbnail.filled()) {
|
||||
ImGui::BeginTooltip();
|
||||
_file_thumbnail.Render(230);
|
||||
ImGui::Text("Thumbnail will be used in\nthe sessions list above.");
|
||||
ImGui::Text("Thumbnail used in the\nlist of Sessions above.");
|
||||
ImGui::EndTooltip();
|
||||
}
|
||||
}
|
||||
@@ -4610,12 +4615,21 @@ void Navigator::RenderMainPannelVimix()
|
||||
//
|
||||
// Current 1. UNDO History
|
||||
//
|
||||
else if (Settings::application.pannel_history_mode > 0) {
|
||||
else if (Settings::application.pannel_current_session_mode > 0) {
|
||||
|
||||
static uint _over = 0;
|
||||
static uint64_t _displayed_over = 0;
|
||||
static bool _tooltip = 0;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.7);
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_BACKSPACE, "Clear undo")) {
|
||||
Action::manager().init();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
// come back...
|
||||
ImGui::SetCursorPos(pos_bot);
|
||||
|
||||
pos_top = ImGui::GetCursorPos();
|
||||
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
if ( ImGui::ListBoxHeader("##UndoHistory", Action::manager().max(), CLAMP(Action::manager().max(), 4, 8)) ) {
|
||||
@@ -4696,12 +4710,21 @@ void Navigator::RenderMainPannelVimix()
|
||||
ImGuiToolkit::ToolTip("Show in view");
|
||||
}
|
||||
//
|
||||
// Current 0. SNAPSHOTS
|
||||
// Current 0. VERSIONS
|
||||
//
|
||||
else {
|
||||
static uint64_t _over = 0;
|
||||
static bool _tooltip = 0;
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_Alpha, 0.7);
|
||||
if (ImGuiToolkit::IconButton( ICON_FA_BACKSPACE, "Clear versions")) {
|
||||
Action::manager().clearSnapshots();
|
||||
}
|
||||
ImGui::PopStyleVar();
|
||||
// come back...
|
||||
ImGui::SetCursorPos(pos_bot);
|
||||
|
||||
// list snapshots
|
||||
std::list<uint64_t> snapshots = Action::manager().snapshots();
|
||||
pos_top = ImGui::GetCursorPos();
|
||||
@@ -4714,7 +4737,7 @@ void Navigator::RenderMainPannelVimix()
|
||||
|
||||
int count_over = 0;
|
||||
ImVec2 size = ImVec2( ImGui::GetContentRegionAvailWidth(), ImGui::GetTextLineHeight() );
|
||||
for (auto snapit = snapshots.begin(); snapit != snapshots.end(); ++snapit)
|
||||
for (auto snapit = snapshots.rbegin(); snapit != snapshots.rend(); ++snapit)
|
||||
{
|
||||
// entry
|
||||
ImVec2 pos = ImGui::GetCursorPos();
|
||||
@@ -4780,7 +4803,7 @@ void Navigator::RenderMainPannelVimix()
|
||||
if (ImGui::BeginPopup( "MenuSnapshot" ) && current > 0 )
|
||||
{
|
||||
_selected = current;
|
||||
ImGui::TextDisabled("Edit snapshot");
|
||||
ImGui::TextDisabled("Edit");
|
||||
// snapshot editable label
|
||||
ImGui::SetNextItemWidth(size.x);
|
||||
if ( ImGuiToolkit::InputText("##Rename", &_snap_label ) )
|
||||
@@ -4788,12 +4811,10 @@ void Navigator::RenderMainPannelVimix()
|
||||
// snapshot thumbnail
|
||||
_snap_thumbnail.Render(size.x);
|
||||
// snapshot actions
|
||||
if (ImGui::Selectable( " " ICON_FA_ANGLE_DOUBLE_RIGHT " Apply", false, 0, size ))
|
||||
if (ImGui::Selectable( " " ICON_FA_ANGLE_DOUBLE_RIGHT " Restore", false, 0, size ))
|
||||
Action::manager().restore();
|
||||
if (ImGui::Selectable( ICON_FA_STAR "_ Remove", false, 0, size ))
|
||||
if (ImGui::Selectable( ICON_FA_CODE_BRANCH "_ Remove", false, 0, size ))
|
||||
Action::manager().remove();
|
||||
if (ImGui::Selectable( ICON_FA_STAR "= Replace", false, 0, size ))
|
||||
Action::manager().replace();
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
else
|
||||
@@ -4813,36 +4834,22 @@ void Navigator::RenderMainPannelVimix()
|
||||
|
||||
// right buttons
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y ));
|
||||
if ( ImGuiToolkit::IconButton( ICON_FA_STAR "+"))
|
||||
Action::manager().snapshot( "Snap" );
|
||||
if ( ImGuiToolkit::IconButton( ICON_FA_FILE_DOWNLOAD " +")) {
|
||||
UserInterface::manager().saveOrSaveAs(true);
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGuiToolkit::ToolTip("Take Snapshot ", CTRL_MOD "Y");
|
||||
ImGuiToolkit::ToolTip("Save & Keep version");
|
||||
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - ImGui::GetFrameHeightWithSpacing()));
|
||||
ImGuiToolkit::HelpMarker("Snapshots keep a list of favorite\n"
|
||||
"status of the current session.\n\n"
|
||||
"Clic an item to preview or edit.\n"
|
||||
"Double-clic to apply.\n");
|
||||
|
||||
// ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
|
||||
// ImGuiToolkit::HelpMarker("Snapshots capture the state of the session.\n"
|
||||
// "Double-clic on a snapshot to restore it.\n\n"
|
||||
// ICON_FA_ROUTE " Enable interpolation to animate\n"
|
||||
// "from current state to snapshot's state.");
|
||||
// // toggle button for smooth interpolation
|
||||
// ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - ImGui::GetFrameHeightWithSpacing()) );
|
||||
// ImGuiToolkit::ButtonToggle(ICON_FA_ROUTE, &Settings::application.smooth_snapshot);
|
||||
// if (ImGui::IsItemHovered())
|
||||
// ImGuiToolkit::ToolTip("Snapshot interpolation");
|
||||
|
||||
// if (Action::manager().currentSnapshot() > 0) {
|
||||
// ImGui::SetCursorPos( pos_bot );
|
||||
// int interpolation = static_cast<int> (Action::manager().interpolation() * 100.f);
|
||||
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
|
||||
// if ( ImGui::SliderInt("Animate", &interpolation, 0, 100, "%d %%") )
|
||||
// Action::manager().interpolate( static_cast<float> ( interpolation ) * 0.01f );
|
||||
|
||||
// }
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
|
||||
ImGuiToolkit::HelpMarker("Previous versions of the session (latest on top).\n"
|
||||
"Double-clic on a version to restore it.\n\n"
|
||||
ICON_FA_CODE_BRANCH " Enable iterative saving to automatically\n"
|
||||
"keep a version each time a session is saved.");
|
||||
// toggle button for versioning
|
||||
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - ImGui::GetFrameHeightWithSpacing()) );
|
||||
ImGuiToolkit::ButtonToggle(" " ICON_FA_CODE_BRANCH " ", &Settings::application.save_version_snapshot);
|
||||
if (ImGui::IsItemHovered())
|
||||
ImGuiToolkit::ToolTip("Iterative saving");
|
||||
|
||||
ImGui::SetCursorPos( pos_bot );
|
||||
}
|
||||
|
||||
@@ -254,6 +254,7 @@ protected:
|
||||
|
||||
void showMenuFile();
|
||||
void showMenuEdit();
|
||||
bool saveOrSaveAs(bool force_versioning = false);
|
||||
void selectSaveFilename();
|
||||
void selectOpenFilename();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user