Recent session files, saved in Settings and restored on start.

This commit is contained in:
brunoherbelin
2020-05-09 19:20:15 +02:00
parent 069009fc06
commit 7634e62054
7 changed files with 176 additions and 98 deletions

View File

@@ -106,6 +106,12 @@ Mixer::Mixer() : session_(nullptr), back_session_(nullptr), current_view_(nullpt
// this initializes with a new empty session
newSession();
// auto load if Settings ask to
if ( Settings::application.recentSessions.automatic ) {
if ( Settings::application.recentSessions.filenames.size() > 0 )
open( Settings::application.recentSessions.filenames.back() );
}
// this initializes with the current view
setCurrentView( (View::Mode) Settings::application.current_view );
}
@@ -115,13 +121,17 @@ void Mixer::update()
{
// swap front and back sessions when loading is finished
if (sessionLoadFinished_) {
// finished loading, swap front and back sessions
swap();
// done
sessionFilename_ = sessionThreadFilename_;
sessionLoadFinished_ = false;
Settings::application.recentSessions.push(sessionFilename_);
}
if (sessionSaveFinished_) {
sessionFilename_ = sessionThreadFilename_;
sessionSaveFinished_ = false;
Settings::application.recentSessions.push(sessionFilename_);
}
// compute dt
@@ -176,13 +186,7 @@ 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");
// in case..
unsetCurrentSource();
// remove source Nodes from views
@@ -191,13 +195,6 @@ void Mixer::deleteSource(Source *s)
// 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)
@@ -334,39 +331,6 @@ void Mixer::saveas(const std::string& filename)
// launch a thread to save the session
std::thread (saveSession, filename, session_).detach();
// XMLDocument xmlDoc;
// XMLElement *version = xmlDoc.NewElement(APP_NAME);
// version->SetAttribute("major", XML_VERSION_MAJOR);
// version->SetAttribute("minor", XML_VERSION_MINOR);
// xmlDoc.InsertEndChild(version);
// // block: list of sources
// XMLElement *session = xmlDoc.NewElement("Session");
// xmlDoc.InsertEndChild(session);
// SourceList::iterator iter;
// for (iter = session_->begin(); iter != session_->end(); iter++)
// {
// SessionVisitor sv(&xmlDoc, session);
// // source visitor
// (*iter)->accept(sv);
// }
// // block: config of views
// XMLElement *views = xmlDoc.NewElement("Views");
// xmlDoc.InsertEndChild(views);
// {
// XMLElement *mixing = xmlDoc.NewElement( "Mixing" );
// mixing->InsertEndChild( SessionVisitor::NodeToXML(*mixing_.scene.root(), &xmlDoc));
// views->InsertEndChild(mixing);
// XMLElement *geometry = xmlDoc.NewElement( "Geometry" );
// geometry->InsertEndChild( SessionVisitor::NodeToXML(*geometry_.scene.root(), &xmlDoc));
// views->InsertEndChild(geometry);
// }
// // save file
// XMLSaveDoc(&xmlDoc, filename);
}
void Mixer::open(const std::string& filename)
@@ -419,6 +383,10 @@ void Mixer::swap()
// reset timer
update_time_ = GST_CLOCK_TIME_NONE;
// delete back
delete back_session_;
back_session_ = nullptr;
}

View File

@@ -68,10 +68,12 @@ public:
protected:
Session *session_;
std::string sessionFilename_;
Session *back_session_;
void swap();
// void validateFilename(const std::string& filename);
std::string sessionFilename_;
void insertSource(Source *s);
void setCurrentSource(SourceList::iterator it);

View File

@@ -1,3 +1,4 @@
#include <algorithm>
#include <iostream>
using namespace std;
@@ -61,7 +62,7 @@ void Settings::Save()
applicationNode->SetAttribute("toolbox", application.toolbox);
pRoot->InsertEndChild(applicationNode);
// block: views
// bloc views
{
XMLElement *viewsNode = xmlDoc.NewElement( "Views" );
viewsNode->SetAttribute("current", application.current_view);
@@ -88,6 +89,37 @@ void Settings::Save()
pRoot->InsertEndChild(viewsNode);
}
// bloc history
{
XMLElement *recent = xmlDoc.NewElement( "Recent" );
XMLElement *recentsession = xmlDoc.NewElement( "Session" );
recentsession->SetAttribute("auto", application.recentSessions.automatic);
for(auto it = application.recentSessions.filenames.begin();
it != application.recentSessions.filenames.end(); it++) {
XMLElement *fileNode = xmlDoc.NewElement("path");
XMLText *text = xmlDoc.NewText( (*it).c_str() );
fileNode->InsertEndChild( text );
recentsession->InsertEndChild(fileNode);
};
recent->InsertEndChild(recentsession);
XMLElement *recentmedia = xmlDoc.NewElement( "Media" );
for(auto it = application.recentMedia.filenames.begin();
it != application.recentMedia.filenames.end(); it++) {
XMLElement *fileNode = xmlDoc.NewElement("uri");
XMLText *text = xmlDoc.NewText( (*it).c_str() );
fileNode->InsertEndChild( text );
recentmedia->InsertEndChild(fileNode);
}
recent->InsertEndChild(recentmedia);
pRoot->InsertEndChild(recent);
}
// First save : create filename
if (settingsFilename.empty())
settingsFilename = SystemToolkit::settings_prepend_path(APP_SETTINGS);
@@ -116,32 +148,9 @@ void Settings::Load()
// different root name
return;
// block: windows
{
application.windows.clear(); // trash existing list
XMLElement * pElement = pRoot->FirstChildElement("Windows");
if (pElement == nullptr) return;
XMLElement* windowNode = pElement->FirstChildElement("Window");
for( ; windowNode ; windowNode=windowNode->NextSiblingElement())
{
const char *pName = windowNode->Attribute("name");
Settings::WindowConfig w(pName);
windowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
windowNode->QueryIntAttribute("y", &w.y);
windowNode->QueryIntAttribute("w", &w.w);
windowNode->QueryIntAttribute("h", &w.h);
windowNode->QueryBoolAttribute("f", &w.fullscreen);
application.windows.push_back(w);
}
}
XMLElement * pElement = pRoot->FirstChildElement("Application");
if (pElement == nullptr) return;
pElement->QueryFloatAttribute("scale", &application.scale);
XMLElement * pElement = pRoot->FirstChildElement("Application");
if (pElement == nullptr) return;
pElement->QueryFloatAttribute("scale", &application.scale);
pElement->QueryIntAttribute("accent_color", &application.accent_color);
pElement->QueryBoolAttribute("preview", &application.preview);
pElement->QueryBoolAttribute("media_player", &application.media_player);
@@ -151,32 +160,90 @@ void Settings::Load()
pElement->QueryBoolAttribute("toolbox", &application.toolbox);
pElement->QueryIntAttribute("stats_corner", &application.stats_corner);
// block: views
// bloc windows
{
application.windows.clear(); // trash existing list
XMLElement * pElement = pRoot->FirstChildElement("Windows");
if (pElement)
{
XMLElement* windowNode = pElement->FirstChildElement("Window");
for( ; windowNode ; windowNode=windowNode->NextSiblingElement())
{
const char *pName = windowNode->Attribute("name");
Settings::WindowConfig w(pName);
windowNode->QueryIntAttribute("x", &w.x); // If this fails, original value is left as-is
windowNode->QueryIntAttribute("y", &w.y);
windowNode->QueryIntAttribute("w", &w.w);
windowNode->QueryIntAttribute("h", &w.h);
windowNode->QueryBoolAttribute("f", &w.fullscreen);
application.windows.push_back(w);
}
}
}
// bloc views
{
application.views.clear(); // trash existing list
XMLElement * pElement = pRoot->FirstChildElement("Views");
if (pElement == nullptr) return;
pElement->QueryIntAttribute("current", &application.current_view);
XMLElement* viewNode = pElement->FirstChildElement("View");
for( ; viewNode ; viewNode=viewNode->NextSiblingElement())
if (pElement)
{
int id = 0;
viewNode->QueryIntAttribute("id", &id);
application.views[id].name = viewNode->Attribute("name");
pElement->QueryIntAttribute("current", &application.current_view);
XMLElement* scaleNode = viewNode->FirstChildElement("default_scale");
tinyxml2::XMLElementToGLM( scaleNode->FirstChildElement("vec3"),
application.views[id].default_scale);
XMLElement* viewNode = pElement->FirstChildElement("View");
for( ; viewNode ; viewNode=viewNode->NextSiblingElement())
{
int id = 0;
viewNode->QueryIntAttribute("id", &id);
application.views[id].name = viewNode->Attribute("name");
XMLElement* translationNode = viewNode->FirstChildElement("default_translation");
tinyxml2::XMLElementToGLM( translationNode->FirstChildElement("vec3"),
application.views[id].default_translation);
XMLElement* scaleNode = viewNode->FirstChildElement("default_scale");
tinyxml2::XMLElementToGLM( scaleNode->FirstChildElement("vec3"),
application.views[id].default_scale);
XMLElement* translationNode = viewNode->FirstChildElement("default_translation");
tinyxml2::XMLElementToGLM( translationNode->FirstChildElement("vec3"),
application.views[id].default_translation);
}
}
}
// bloc history of recent
{
XMLElement * pElement = pRoot->FirstChildElement("Recent");
if (pElement)
{
// recent session filenames
XMLElement * pSession = pElement->FirstChildElement("Session");
if (pSession)
{
pSession->QueryBoolAttribute("auto", &application.recentSessions.automatic);
application.recentSessions.filenames.clear();
XMLElement* path = pSession->FirstChildElement("path");
for( ; path ; path = path->NextSiblingElement())
{
application.recentSessions.push( std::string (path->GetText()) );
}
}
// recent media uri
XMLElement * pMedia = pElement->FirstChildElement("Media");
if (pMedia)
{
application.recentMedia.filenames.clear();
XMLElement* path = pMedia->FirstChildElement("path");
for( ; path ; path = path->NextSiblingElement())
{
application.recentMedia.push( std::string (path->GetText()) );
}
}
}
}
}

View File

@@ -6,6 +6,7 @@
#include <string>
#include <map>
#include <vector>
#include <list>
#include <glm/glm.hpp>
namespace Settings {
@@ -33,6 +34,22 @@ struct ViewConfig
};
struct History
{
std::list<std::string> filenames;
bool automatic;
History() {
automatic = false;
}
void push(std::string filename) {
filenames.remove(filename);
filenames.push_front(filename);
if (filenames.size() > MAX_RECENT_HISTORY)
filenames.pop_back();
}
};
struct Application
{
// Verification
@@ -54,9 +71,13 @@ struct Application
std::map<int, ViewConfig> views;
// multiple windows handling
// TODO: maybe keep map of multiple windows, widn id=0 for main window
// TODO: manage other windows
std::vector<WindowConfig> windows;
// recent files histories
History recentSessions;
History recentMedia;
Application() : name(APP_NAME){
scale = 1.f;
accent_color = 0;

View File

@@ -2,6 +2,7 @@
#include <cstring>
#include <sstream>
#include <thread>
#include <algorithm>
// ImGui
#include "imgui.h"
@@ -100,6 +101,10 @@ static void FileDialogSave(std::string path)
else
{
FileDialogFilename_ = std::string( save_file_name );
// check extension
std::string extension = FileDialogFilename_.substr(FileDialogFilename_.find_last_of(".") + 1);
if (extension != "vmx")
FileDialogFilename_ += ".vmx";
}
FileDialogSaveFinished_ = true;
@@ -186,14 +191,16 @@ void UserInterface::handleKeyboard()
}
else if (ImGui::IsKeyPressed( GLFW_KEY_O )) {
// Open session
std::thread (FileDialogOpen, "./").detach();
navigator.hidePannel();
}
else if (ImGui::IsKeyPressed( GLFW_KEY_S )) {
// Save Session
std::cerr <<" Save File " << std::endl;
Mixer::manager().save();
}
else if (ImGui::IsKeyPressed( GLFW_KEY_W )) {
// New Session
std::cerr <<" Close File " << std::endl;
Mixer::manager().newSession();
}
else if (ImGui::IsKeyPressed( GLFW_KEY_L )) {
// Logs
@@ -1035,10 +1042,23 @@ void Navigator::RenderMainPannel()
ImGui::EndMenu();
}
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
static int recent_session = 0;
if ( ImGui::Combo("Recent", &recent_session, "Select\0") ) {
// combo box with list of recent session files from Settings
static bool recentselected = false;
recentselected = false;
if (ImGui::BeginCombo("Recent", "Select"))
{
std::for_each(Settings::application.recentSessions.filenames.begin(),
Settings::application.recentSessions.filenames.end(), [](std::string& filename) {
if (ImGui::Selectable( filename.substr( filename.size() - 40 ).c_str() )) {
Mixer::manager().open( filename );
recentselected = true;
}
});
ImGui::EndCombo();
}
if (recentselected)
hidePannel();
ImGuiToolkit::ButtonSwitch( "Load most recent on start", &Settings::application.recentSessions.automatic);
ImGui::Text(" ");
ImGui::Text("Windows");

View File

@@ -79,7 +79,6 @@ class UserInterface
// } FileDialogStatus;
// FileDialogStatus filestatus_;
// std::string filename_;
// std::thread filethread_;
// void startOpenFileDialog();
// Private Constructor

View File

@@ -8,6 +8,7 @@
#define APP_VERSION_MINOR 1
#define XML_VERSION_MAJOR 0
#define XML_VERSION_MINOR 1
#define MAX_RECENT_HISTORY 10
#define MINI(a, b) (((a) < (b)) ? (a) : (b))
#define MAXI(a, b) (((a) > (b)) ? (a) : (b))