New button to reorder the list of sessions and of media files

In navigator panel, the list of sessions can be reordered either alphabetically or by file modification date. Same for list of media files for creating a new media source.
This commit is contained in:
Bruno Herbelin
2023-09-03 00:08:30 +02:00
parent 58e5dd9186
commit fb3ee2aa8c
6 changed files with 136 additions and 49 deletions

Binary file not shown.

View File

@@ -321,10 +321,12 @@ struct Application
std::vector<WindowConfig> windows;
// recent files histories
int orderingSessions;
History recentSessions;
History recentFolders;
History recentImport;
History recentImportFolders;
int orderingImportFolder;
History recentRecordings;
std::map< std::string, std::string > dialogRecentFolder;
@@ -361,6 +363,8 @@ struct Application
windows = std::vector<WindowConfig>(1+MAX_OUTPUT_WINDOW);
windows[0].w = 1600;
windows[0].h = 900;
orderingSessions = 3;
orderingImportFolder = 3;
}
};

View File

@@ -280,6 +280,70 @@ string SystemToolkit::full_filename(const std::string& path, const string &filen
return fullfilename;
}
unsigned long SystemToolkit::file_modification_time(const std::string& path)
{
if (file_exists(path)) {
struct stat statsfile;
// fill statistics of given file path
if( stat( path.c_str(), &statsfile) > -1 ) {
// return modification time
return (unsigned long) statsfile.st_mtime;
}
}
return 0;
}
std::string SystemToolkit::file_modification_time_string(const std::string& path)
{
ostringstream oss;
if (file_exists(path)) {
struct stat statsfile;
// fill statistics of given file path
if( stat( path.c_str(), &statsfile) > -1 ) {
// read modification time
tm *datetime = localtime(&statsfile.st_mtime);
ostringstream oss;
oss << setw(4) << setfill('0') << to_string(datetime->tm_year + 1900);
oss << setw(2) << setfill('0') << to_string(datetime->tm_mon + 1);
oss << setw(2) << setfill('0') << to_string(datetime->tm_mday );
oss << setw(2) << setfill('0') << to_string(datetime->tm_hour );
oss << setw(2) << setfill('0') << to_string(datetime->tm_min );
oss << setw(2) << setfill('0') << to_string(datetime->tm_sec );
}
}
return oss.str();
}
void SystemToolkit::reorder_file_list(std::list<string> &filelist, Ordering m)
{
if ( m >= DATE ) {
auto dateComparator = [](const std::string &a, const std::string &b) {
return SystemToolkit::file_modification_time(a) < SystemToolkit::file_modification_time(b);
};
filelist.sort( dateComparator );
if ( m == DATE_INVERSE )
filelist.reverse();
}
else {
auto alphaComparator = [](const std::string &a, const std::string &b) {
std::string _a = a;
std::string _b = b;
std::transform(_a.begin(), _a.end(), _a.begin(), ::tolower);
std::transform(_b.begin(), _b.end(), _b.begin(), ::tolower);
return _a < _b;
};
filelist.sort( alphaComparator );
if ( m == ALPHA_INVERSE )
filelist.reverse();
}
}
bool SystemToolkit::file_exists(const string& path)
{
if (path.empty())
@@ -307,7 +371,7 @@ string SystemToolkit::path_directory(const string& path)
return directorypath;
}
list<string> SystemToolkit::list_directory(const string& path, const list<string>& patterns)
list<string> SystemToolkit::list_directory(const string& path, const list<string>& patterns, Ordering m)
{
list<string> ls;
@@ -329,7 +393,7 @@ list<string> SystemToolkit::list_directory(const string& path, const list<string
closedir (dir);
}
ls.sort();
reorder_file_list( ls, m );
return ls;
}

View File

@@ -49,9 +49,6 @@ namespace SystemToolkit
// tests if dir is a directory and return its path, empty string otherwise
std::string path_directory(const std::string& path);
// list all files of a directory mathing the given filter extension (if any)
std::list<std::string> list_directory(const std::string& path, const std::list<std::string> &patterns);
// builds a path relative to 'relativeTo' to reach file at 'absolutePath' (e.g. /a/b/c/d rel to /a/b/e -> ../c/d)
std::string path_relative_to_path(const std::string& absolutePath, const std::string& relativeTo);
@@ -64,6 +61,23 @@ namespace SystemToolkit
// generates a filename at given path, with basename and date prefix
std::string filename_dateprefix(const std::string& path, const std::string& base, const std::string& extension);
// Get modification time of file, as string YYYYMMDDHHmmss
unsigned long file_modification_time(const std::string& path);
std::string file_modification_time_string(const std::string& path);
typedef enum {
ALPHA = 0,
ALPHA_INVERSE = 1,
DATE = 2,
DATE_INVERSE = 3
} Ordering;
//
void reorder_file_list(std::list<std::string> &filelist, Ordering m);
// list all files of a directory mathing the given filter extension (if any)
std::list<std::string> list_directory(const std::string& path, const std::list<std::string> &patterns, Ordering m = ALPHA);
// true of file exists
bool file_exists(const std::string& path);

View File

@@ -2649,6 +2649,11 @@ void UserInterface::RenderHelp()
///
/// NAVIGATOR
///
///
std::vector< std::pair<int, int> > Navigator::icons_ordering_files = { {2,12}, {3,12}, {4,12}, {5,12} };
std::vector< std::string > Navigator::tooltips_ordering_files = { "Alphabetical", "Invert alphabetical", "Older files first", "Recent files first" };
Navigator::Navigator()
{
// default geometry
@@ -3480,7 +3485,8 @@ void Navigator::RenderNewPannel()
// MODE LIST FOLDER
else if ( new_media_mode == MEDIA_FOLDER) {
// show list of media files in folder
sourceMediaFiles = SystemToolkit::list_directory( Settings::application.recentImportFolders.path, { MEDIA_FILES_PATTERN });
sourceMediaFiles = SystemToolkit::list_directory( Settings::application.recentImportFolders.path, { MEDIA_FILES_PATTERN },
(SystemToolkit::Ordering) Settings::application.orderingImportFolder);
}
// indicate the list changed (do not change at every frame)
new_media_mode_changed = false;
@@ -3524,9 +3530,10 @@ void Navigator::RenderNewPannel()
ImGui::ListBoxFooter();
}
// Supplementary icons to manage the list
ImVec2 pos_bot = ImGui::GetCursorPos();
// Bottom Right side of the list: helper and options of Recent Recordings
if (new_media_mode == MEDIA_RECORDING) {
// Bottom Right side of the list: helper and options
ImVec2 pos_bot = ImGui::GetCursorPos();
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
ImGuiToolkit::HelpToolTip("Recently recorded videos (lastest on top). Clic on a filename to open.\n\n"
ICON_FA_CHEVRON_CIRCLE_RIGHT " Auto-preload prepares this panel with the "
@@ -3541,9 +3548,18 @@ void Navigator::RenderNewPannel()
new_source_preview_.setSource( Mixer::manager().createSourceFile(sourceMediaFileCurrent), label);
}
}
// come back...
ImGui::SetCursorPos(pos_bot);
}
// Top right of Media folder list
else if (new_media_mode == MEDIA_FOLDER) {
// ordering list
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y) );
ImGui::PushID("##new_media_mode_changed");
if ( ImGuiToolkit::IconMultistate(icons_ordering_files, &Settings::application.orderingImportFolder, tooltips_ordering_files) )
new_media_mode_changed = true;
ImGui::PopID();
}
// come back...
ImGui::SetCursorPos(pos_bot);
}
// Sequence Source creator
@@ -4103,14 +4119,18 @@ void Navigator::RenderMainPannelVimix()
// show list of recent sessions
Settings::application.recentSessions.validate();
sessions_list = Settings::application.recentSessions.filenames;
Settings::application.recentSessions.changed = false;
SystemToolkit::reorder_file_list( sessions_list, (SystemToolkit::Ordering) Settings::application.orderingSessions);
}
// selection MODE 1 : LIST FOLDER
else if ( selection_session_mode == 1) {
// show list of vimix files in folder
sessions_list = SystemToolkit::list_directory( Settings::application.recentFolders.path, { VIMIX_FILE_PATTERN });
sessions_list = SystemToolkit::list_directory( Settings::application.recentFolders.path, { VIMIX_FILE_PATTERN },
(SystemToolkit::Ordering) Settings::application.orderingSessions);
}
// indicate the list changed (do not change at every frame)
Settings::application.recentSessions.changed = false;
Settings::application.recentFolders.changed = false;
selection_session_mode_changed = false;
_file_over = sessions_list.end();
_displayed_over = sessions_list.end();
@@ -4219,8 +4239,16 @@ void Navigator::RenderMainPannelVimix()
if (ImGui::IsItemHovered())
ImGuiToolkit::ToolTip("New session", SHORTCUT_NEW_FILE);
// ordering list
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_top.y + ImGui::GetFrameHeightWithSpacing()) );
ImGui::PushID("##selection_session_mode_changed");
if ( ImGuiToolkit::IconMultistate(icons_ordering_files, &Settings::application.orderingSessions, tooltips_ordering_files) )
selection_session_mode_changed = true;
ImGui::PopID();
// help indicator
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
ImGuiToolkit::HelpToolTip("Here are listed either all recent files or all the sessions files inside a selected folder (*.mix) .\n\n"
ImGuiToolkit::HelpToolTip("Here are listed either the recent files or all the sessions files (*.mix) in a selected folder.\n\n"
"Double-clic on a filename to open the session.\n\n"
ICON_FA_ARROW_CIRCLE_RIGHT " Smooth transition "
"performs cross fading to the opened session.");
@@ -4262,35 +4290,6 @@ void Navigator::RenderMainPannelVimix()
ImGui::InputText("##Info", (char *)info.c_str(), info.size(), ImGuiInputTextFlags_ReadOnly);
ImGui::PopStyleColor(1);
// Kept for later? Larger info box with more details on the session file...
// ImGuiTextBuffer info;
// if (!sessionfilename.empty())
// info.appendf("%s\n", SystemToolkit::filename(sessionfilename).c_str());
// else
// info.append("<unsaved>\n");
// info.appendf("%dx%dpx", output->width(), output->height());
// if (p.x > -1)
// info.appendf(", %s", FrameBuffer::aspect_ratio_name[p.x]);
// // content info
// const uint N = Mixer::manager().session()->numSource();
// if (N > 1)
// info.appendf("\n%d sources", N);
// else if (N > 0)
// info.append("\n1 source");
// const size_t M = MediaPlayer::registered().size();
// if (M > 0) {
// info.appendf("\n%d media files:", M);
// for (auto mit = MediaPlayer::begin(); mit != MediaPlayer::end(); ++mit)
// info.appendf("\n- %s", SystemToolkit::filename((*mit)->filename()).c_str());
// }
// // Show info text bloc (multi line, dark background)
// ImGuiToolkit::PushFont( ImGuiToolkit::FONT_MONO );
// ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0.14f, 0.14f, 0.14f, 0.9f));
// ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
// ImGui::InputTextMultiline("##Info", (char *)info.c_str(), info.size(), ImVec2(IMGUI_RIGHT_ALIGN, 2*ImGui::GetTextLineHeightWithSpacing()), ImGuiInputTextFlags_ReadOnly);
// ImGui::PopStyleColor(1);
// ImGui::PopFont();
// change resolution (height only)
// get parameters to edit resolution
glm::ivec2 preset = RenderView::presetFromResolution(output->resolution());
@@ -4375,7 +4374,7 @@ void Navigator::RenderMainPannelVimix()
// Thumbnail
static Thumbnail _file_thumbnail;
static FrameBufferImage *thumbnail = nullptr;
if ( ImGui::Button( ICON_FA_TAG " New thumbnail", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) {
if ( ImGui::Button( ICON_FA_TAG " Create thumbnail", ImVec2(IMGUI_RIGHT_ALIGN, 0)) ) {
Mixer::manager().session()->setThumbnail();
thumbnail = nullptr;
}
@@ -4647,8 +4646,8 @@ void Navigator::RenderMainPannelVimix()
ImGui::SetCursorPos( ImVec2( pannel_width_ IMGUI_RIGHT_ALIGN, pos_bot.y - 2.f * ImGui::GetFrameHeightWithSpacing()));
ImGuiToolkit::HelpToolTip("Previous versions of the session (latest on top). "
"Double-clic on a version to restore it.\n\n"
ICON_FA_CODE_BRANCH " Iterative saving automatically "
"keeps a version each time a session is saved.");
ICON_FA_CODE_BRANCH " With iterative saving on, a new version "
"is kept each time the 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,"Iterative saving");
@@ -4803,8 +4802,8 @@ void Navigator::RenderMousePointerSelector(const ImVec2 &size)
ImGui::SameLine(0, IMGUI_SAME_LINE * 3);
ImGuiToolkit::ButtonToggle(Settings::application.mouse_pointer_lock ? ICON_FA_LOCK ALT_LOCK : ICON_FA_UNLOCK ALT_LOCK,
&Settings::application.mouse_pointer_lock,
"Activate the selected snap mouse pointer by pressing the [" ALT_MOD "] key.\n\n"
ICON_FA_LOCK ALT_LOCK " keeps the snap mouse pointer active.");
"Activate the selected Snap mouse cursor by pressing the [" ALT_MOD "] key.\n\n"
ICON_FA_LOCK ALT_LOCK " keeps the Snap mouse cursor active.");
// slider to adjust strength of the mouse pointer
ImGui::SetNextItemWidth( IMGUI_RIGHT_ALIGN );
@@ -4821,12 +4820,15 @@ void Navigator::RenderMousePointerSelector(const ImVec2 &size)
}
// special case of GRID
else {
static const char* grid_names[Grid::UNIT_ONE+1] = { "Precise (0.05)", "Small (0.1)", "Default (0.2)", "Large (0.5)", "Huge (1.0)"};
static const char* grid_names[Grid::UNIT_ONE+1] = { "Precise", "Small", "Default", "Large", "Huge"};
int grid_current = (Grid::Units) round( *val * 4.f) ;
const char* grid_current_name = (grid_current >= 0 && grid_current <= Grid::UNIT_ONE) ?
grid_names[grid_current] : "Unknown";
if (ImGui::SliderInt("##slidergrid", &grid_current, 0, Grid::UNIT_ONE, grid_current_name) ) {
if (ImGui::SliderInt("##slidergrid", &grid_current, 0, Grid::UNIT_ONE, grid_current_name) )
*val = (float) grid_current * 0.25f;
if (ImGui::IsItemHovered() && g.IO.MouseWheel != 0.f ){
*val += 0.25f * g.IO.MouseWheel;
*val = CLAMP( *val, 0.f, 1.f);
}
}
ImGui::SameLine(0, IMGUI_SAME_LINE);

View File

@@ -110,6 +110,9 @@ private:
MediaCreateMode new_media_mode;
bool new_media_mode_changed;
Source *source_to_replace;
static std::vector< std::pair<int, int> > icons_ordering_files;
static std::vector< std::string > tooltips_ordering_files;
};
class ToolBox