mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Recent session files, saved in Settings and restored on start.
This commit is contained in:
62
Mixer.cpp
62
Mixer.cpp
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
4
Mixer.h
4
Mixer.h
@@ -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);
|
||||
|
||||
|
||||
153
Settings.cpp
153
Settings.cpp
@@ -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()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
23
Settings.h
23
Settings.h
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -79,7 +79,6 @@ class UserInterface
|
||||
// } FileDialogStatus;
|
||||
// FileDialogStatus filestatus_;
|
||||
// std::string filename_;
|
||||
// std::thread filethread_;
|
||||
// void startOpenFileDialog();
|
||||
|
||||
// Private Constructor
|
||||
|
||||
Reference in New Issue
Block a user