Rework file widget to prevent partial hang

This commit is contained in:
Jamie Vital 2023-09-24 09:14:16 -04:00
parent ddb3434a94
commit 15aeb83661
8 changed files with 168 additions and 128 deletions

View file

@ -8,7 +8,7 @@
FileSource::FileSource(dsp::SourceDescriptor source) : DSPSampleSource(source)
{
file_input.default_dir = satdump::config::main_cfg["satdump_directories"]["default_input_directory"]["value"].get<std::string>();
file_input.setPath(satdump::config::main_cfg["satdump_directories"]["default_input_directory"]["value"].get<std::string>());
should_run = true;
work_thread = std::thread(&FileSource::run_thread, this);
}

View file

@ -81,7 +81,7 @@ namespace satdump
d_type = PARAM_PATH;
file_select = std::make_shared<FileSelectWidget>(p_json["name"], p_json["name"], p_json["is_directory"]);
file_select->path = p_json["value"];
file_select->setPath(p_json["value"]);
}
else if (type_str == "timestamp")
{
@ -173,7 +173,7 @@ namespace satdump
}
}
else if (d_type == PARAM_PATH)
file_select->path = v.get<std::string>();
file_select->setPath(v.get<std::string>());
else if (d_type == PARAM_TIMESTAMP)
date_time_picker->set(v.get<double>());
else if (d_type == PARAM_NOTATED_INT)

View file

@ -0,0 +1,140 @@
#include <filesystem>
#include "widget.h"
#include "core/style.h"
#include "imgui/imgui.h"
#include "imgui/imgui_stdlib.h"
#include "android_dialogs.h"
#ifdef _MSC_VER
#include <direct.h>
#endif
FileSelectWidget::FileSelectWidget(std::string label, std::string selection_text, bool directory)
: label(label), selection_text(selection_text), directory(directory)
{
fileselect = nullptr;
dirselect = nullptr;
waiting_for_res = false;
default_dir = ".";
id = "##filepathselection" + label;
btnid = u8"\ufc6e Open##filepathselectionbutton" + label;
}
FileSelectWidget::~FileSelectWidget()
{
delete fileselect;
delete dirselect;
}
bool FileSelectWidget::draw(std::string hint)
{
bool changed = false;
bool disabled = waiting_for_res;
bool is_dir = std::filesystem::is_directory(path);
file_valid = std::filesystem::exists(path) && (directory ? is_dir : !is_dir);
#ifdef _MSC_VER
if (default_dir == ".")
{
char* cwd;
cwd = _getcwd(NULL, 0);
if (cwd != 0)
default_dir = cwd;
}
#endif
if (disabled)
style::beginDisabled();
if (!file_valid)
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
changed |= ImGui::InputTextWithHint(id.c_str(), hint.c_str(), &path);
if (!file_valid)
ImGui::PopStyleColor();
ImGui::SameLine();
if (ImGui::Button(btnid.c_str()))
{
if (!directory)
{
#ifdef __ANDROID__
show_select_file_dialog();
#else
fileselect = new pfd::open_file(selection_text.c_str(), default_dir, { "All Files", "*" }, pfd::opt::force_path);
#endif
}
else
{
#ifdef __ANDROID__
show_select_directory_dialog();
#else
dirselect = new pfd::select_folder(selection_text.c_str(), default_dir, pfd::opt::force_path);
#endif
}
waiting_for_res = true;
}
if (disabled)
style::endDisabled();
if (waiting_for_res)
{
std::string get = "";
#ifdef __ANDROID__
if (!directory)
get = get_select_file_dialog_result();
else
get = get_select_directory_dialog_result();
if (get != "")
{
{
#else
bool is_ready = (directory ? dirselect->ready(0) : fileselect->ready(0));
if (is_ready)
{
if (!directory)
{
get = (fileselect->result().size() == 0 ? "" : fileselect->result()[0]);
delete fileselect;
fileselect = nullptr;
}
else
{
get = dirselect->result();
delete dirselect;
dirselect = nullptr;
}
if (get == "")
waiting_for_res = false;
else
{
#endif
path = get;
changed = true;
file_valid = std::filesystem::exists(path) && (directory ? is_dir : !is_dir);
waiting_for_res = false;
}
}
}
return file_valid && changed;
}
std::string FileSelectWidget::getPath()
{
return path;
}
void FileSelectWidget::setPath(std::string new_path)
{
path = new_path;
}
void FileSelectWidget::setDefaultDir(std::string new_path)
{
default_dir = new_path;
}
bool FileSelectWidget::isValid()
{
return file_valid;
}

View file

@ -1,124 +1,21 @@
#pragma once
#include "imgui/imgui.h"
#include <filesystem>
#include "portable-file-dialogs.h"
#include "imgui/imgui_stdlib.h"
#include "android_dialogs.h"
#ifdef _MSC_VER
#include <direct.h>
#endif
struct FileSelectWidget
class FileSelectWidget
{
std::string label;
std::string selection_text;
std::string id;
std::string btnid;
public:
FileSelectWidget(std::string label, std::string selection_text, bool directory = false);
~FileSelectWidget();
bool draw(std::string hint = "");
bool isValid();
std::string getPath();
void setPath(std::string new_path);
void setDefaultDir(std::string new_path);
std::string path;
private:
std::string label, selection_text, id, btnid, default_dir, path;
bool directory, waiting_for_res;
pfd::open_file *fileselect;
pfd::select_folder *dirselect;
bool file_valid;
bool directory;
#ifdef __ANDROID__
bool waiting_for_res = false;
#endif
std::string default_dir = ".";
bool draw(std::string hint = "")
{
bool changed = false;
bool is_dir = std::filesystem::is_directory(path);
file_valid = std::filesystem::exists(path) && (directory ? is_dir : !is_dir);
#ifdef _MSC_VER
if (default_dir == ".")
{
char* cwd;
cwd = _getcwd(NULL, 0);
if (cwd != 0)
default_dir = cwd;
}
#endif
if (!file_valid)
ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 0, 0, 255));
changed |= ImGui::InputTextWithHint(id.c_str(), hint.c_str(), &path);
if (!file_valid)
ImGui::PopStyleColor();
ImGui::SameLine();
if (ImGui::Button(btnid.c_str()))
{
if (!directory)
{
#ifdef __ANDROID__
show_select_file_dialog();
#else
auto fileselect = pfd::open_file(selection_text.c_str(), default_dir, { "All Files", "*" }, pfd::opt::force_path);
while (!fileselect.ready(1000))
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (fileselect.result().size() > 0)
path = fileselect.result()[0];
#endif
}
else
{
#ifdef __ANDROID__
show_select_directory_dialog();
#else
auto dirselect = pfd::select_folder(selection_text.c_str(), default_dir, pfd::opt::force_path);
while (!dirselect.ready(1000))
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (dirselect.result().size() > 0)
path = dirselect.result();
#endif
}
changed = true;
#ifdef __ANDROID__
waiting_for_res = true;
#endif
file_valid = std::filesystem::exists(path) && (directory ? is_dir : !is_dir);
}
#ifdef __ANDROID__
if (waiting_for_res)
{
std::string get;
if (!directory)
get = get_select_file_dialog_result();
else
get = get_select_directory_dialog_result();
if (get != "")
{
path = get;
changed = true;
file_valid = std::filesystem::exists(path) && (directory ? is_dir : !is_dir);
waiting_for_res = false;
}
}
#endif
return file_valid && changed;
}
FileSelectWidget(std::string label, std::string selection_text, bool directory = false)
: label(label), selection_text(selection_text), directory(directory)
{
id = "##filepathselection" + label;
btnid = u8"\ufc6e Open##filepathselectionbutton" + label;
}
std::string getPath()
{
return path;
}
};

View file

@ -16,9 +16,8 @@ namespace satdump
void setup()
{
pipeline_selector = std::make_unique<PipelineUISelector>(false);
pipeline_selector->inputfileselect.default_dir = config::main_cfg["satdump_directories"]["default_input_directory"]["value"].get<std::string>();
pipeline_selector->outputdirselect.default_dir = config::main_cfg["satdump_directories"]["default_output_directory"]["value"].get<std::string>();
pipeline_selector->inputfileselect.setDefaultDir(config::main_cfg["satdump_directories"]["default_input_directory"]["value"].get<std::string>());
pipeline_selector->outputdirselect.setDefaultDir(config::main_cfg["satdump_directories"]["default_output_directory"]["value"].get<std::string>());
#ifndef _MSC_VER
pipeline_selector->inputfileselect.default_dir += "/";
@ -46,9 +45,9 @@ namespace satdump
{
nlohmann::json params2 = pipeline_selector->getParameters();
if (!pipeline_selector->inputfileselect.file_valid)
if (!pipeline_selector->inputfileselect.isValid())
error_message = "Input file is invalid!";
else if (!pipeline_selector->outputdirselect.file_valid)
else if (!pipeline_selector->outputdirselect.isValid())
error_message = "Output folder is invalid!";
else
ui_thread_pool.push([&, params2](int)

View file

@ -145,7 +145,7 @@ namespace satdump
void RecorderApplication::start_processing()
{
if (pipeline_selector.outputdirselect.file_valid || automated_live_output_dir)
if (pipeline_selector.outputdirselect.isValid() || automated_live_output_dir)
{
logger->trace("Start pipeline...");
pipeline_params = pipeline_selector.getParameters();

View file

@ -14,6 +14,10 @@
#include "core/opencl.h"
#include "common/widgets/switch.h"
#ifdef _MSC_VER
#include <direct.h>
#endif
namespace satdump
{
void ImageViewerHandler::init()

View file

@ -205,8 +205,8 @@ namespace satdump
projection_new_layer_cfg.draw("Projection Config File");
}
if (ImGui::Button("Add layer") && (selected_external_type == 2 || (projection_new_layer_file.file_valid &&
(selected_external_type == 0 ? 1 : projection_new_layer_cfg.file_valid))))
if (ImGui::Button("Add layer") && (selected_external_type == 2 || (projection_new_layer_file.isValid() &&
(selected_external_type == 0 ? 1 : projection_new_layer_cfg.isValid()))))
{
if (re_matchp(osm_url_regex, mapurl.c_str(), &osm_url_regex_len) || selected_external_type != 2)
{