From 6d6658c610f2559c0832352a09ac703f8b3450d2 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Wed, 30 Jun 2021 20:26:23 +0800 Subject: [PATCH 01/11] Add fc2dconfig program This commit will add a new dependency: wxWidgets. --- CMakeLists.txt | 7 +++++++ src/fc2dconfig.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/fc2dconfig.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dfba7be..201e538 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,9 @@ find_package( glm REQUIRED ) message (STATUS "Found glm at: " ${GLM_INCLUDE_DIRS} ) find_package( FreeGLUT REQUIRED ) message (STATUS "Found FreeGLUT at: " ${GLUT_INCLUDE_DIR} ) +find_package( wxWidgets REQUIRED core base ) +message (STATUS "Found wxWidgets at: " ${wxWidgets_USE_FILE} ) +include( ${wxWidgets_USE_FILE} ) include_directories( ${OpenCV_INCLUDE_DIRS} ) include_directories( ${OPENGL_INCLUDE_DIR} ) include_directories( ${GLEW_INCLUDE_DIRS} ) @@ -65,3 +68,7 @@ add_executable( fc2d ) target_link_libraries( fc2d ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${WEBP_LIBRARIES} FreeGLUT::freeglut GLEW::glew zip Boxer fmt ) +add_executable( fc2dconfig + src/fc2dconfig.cpp +) +target_link_libraries( fc2dconfig ${wxWidgets_LIBRARIES} ) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp new file mode 100644 index 0000000..f9711df --- /dev/null +++ b/src/fc2dconfig.cpp @@ -0,0 +1,48 @@ +#include + +#include +#ifndef WX_PRECOMP +#include +#endif + +class ConfigurationApp : public wxApp { + public: + virtual bool OnInit(); +}; + +class ConfigurationFrame : public wxFrame { + public: + ConfigurationFrame(); + private: + void OnExit(wxCommandEvent& event); +}; + +wxIMPLEMENT_APP(ConfigurationApp); + +bool ConfigurationApp::OnInit() { + // TODO: put config file creation here + ConfigurationFrame* frame = new ConfigurationFrame(); + frame->Show(true); + return true; +} + +ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " PROJECT_NAME) { + wxPanel* panel = new wxPanel(this, wxID_ANY); + + wxStaticText* placeholderText = new wxStaticText(panel, wxID_ANY, "There's nothing here right now, just click OK."); + wxButton* okButton = new wxButton(panel, wxID_OK, "OK"); + + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + sizer->Add(placeholderText, 0, wxALL | wxALIGN_LEFT, 10); + sizer->AddStretchSpacer(1); + sizer->Add(okButton, 0, wxALIGN_RIGHT | wxALL, 10); + + panel->SetSizerAndFit(sizer); + + Bind(wxEVT_BUTTON, &ConfigurationFrame::OnExit, this, wxID_OK); +} + +void ConfigurationFrame::OnExit(wxCommandEvent& event) { + // TODO: write config file here + Close(true); +} From d63178a37b21b3f8c60a4d62325ce5dacf0bd15a Mon Sep 17 00:00:00 2001 From: Epicalert Date: Thu, 1 Jul 2021 22:47:13 +0800 Subject: [PATCH 02/11] Add working config file system `fc2dconfig` will write a config file, and `fc2d` will read it. --- CMakeLists.txt | 2 ++ src/configfile.cpp | 25 +++++++++++++++++++++++++ src/configfile.hpp | 8 ++++++++ src/fc2dconfig.cpp | 24 +++++++++++++++++++++++- src/main.cpp | 15 +++++++++++---- 5 files changed, 69 insertions(+), 5 deletions(-) create mode 100644 src/configfile.cpp create mode 100644 src/configfile.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 201e538..dcb0eb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,10 +65,12 @@ add_executable( fc2d src/tomlcpp.cpp src/error.cpp src/eye.cpp + src/configfile.cpp ) target_link_libraries( fc2d ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${WEBP_LIBRARIES} FreeGLUT::freeglut GLEW::glew zip Boxer fmt ) add_executable( fc2dconfig src/fc2dconfig.cpp + src/paths.cpp ) target_link_libraries( fc2dconfig ${wxWidgets_LIBRARIES} ) diff --git a/src/configfile.cpp b/src/configfile.cpp new file mode 100644 index 0000000..9e95d3c --- /dev/null +++ b/src/configfile.cpp @@ -0,0 +1,25 @@ +#include +#include + +#include +#include +#include +#include + +bool configFileOpen(struct optData* data) { + auto configFile = toml::parseFile(prefixCustom + "config.toml"); + if (!configFile.table) { + return false; + } + + auto useHaarResult = configFile.table->getBool("use_haar"); + if (useHaarResult.first) { + data->useHaar = useHaarResult.second; + } + auto modelNameResult = configFile.table->getString("model"); + if (modelNameResult.first) { + data->model = modelNameResult.second; + } + + return true; +} diff --git a/src/configfile.hpp b/src/configfile.hpp new file mode 100644 index 0000000..3dd9fd9 --- /dev/null +++ b/src/configfile.hpp @@ -0,0 +1,8 @@ +#ifndef CONFIGFILE_HPP +#define CONFIGFILE_HPP + +#include + +bool configFileOpen(struct optData* optData); + +#endif diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index f9711df..c3ad3ab 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -1,4 +1,8 @@ +#include + #include +#include +#include #include #ifndef WX_PRECOMP @@ -14,13 +18,18 @@ class ConfigurationFrame : public wxFrame { public: ConfigurationFrame(); private: + wxCheckBox* useHaarCheckBox; + wxTextCtrl* modelNameText; void OnExit(wxCommandEvent& event); }; wxIMPLEMENT_APP(ConfigurationApp); bool ConfigurationApp::OnInit() { + initPrefixes(); + // TODO: put config file creation here + ConfigurationFrame* frame = new ConfigurationFrame(); frame->Show(true); return true; @@ -29,11 +38,18 @@ bool ConfigurationApp::OnInit() { ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " PROJECT_NAME) { wxPanel* panel = new wxPanel(this, wxID_ANY); + // TODO: load config file and populate values wxStaticText* placeholderText = new wxStaticText(panel, wxID_ANY, "There's nothing here right now, just click OK."); + useHaarCheckBox = new wxCheckBox(panel, wxID_ANY, "Disable DNN face detection"); + // TODO: make this a dropdown with the detected model files + modelNameText = new wxTextCtrl(panel, wxID_ANY, "test"); + // TODO: cancel button to exit without saving settings wxButton* okButton = new wxButton(panel, wxID_OK, "OK"); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(placeholderText, 0, wxALL | wxALIGN_LEFT, 10); + sizer->Add(useHaarCheckBox, 0, wxALL | wxALIGN_LEFT, 5); + sizer->Add(modelNameText, 0, wxALL | wxALIGN_LEFT, 5); sizer->AddStretchSpacer(1); sizer->Add(okButton, 0, wxALIGN_RIGHT | wxALL, 10); @@ -43,6 +59,12 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " } void ConfigurationFrame::OnExit(wxCommandEvent& event) { - // TODO: write config file here + // write options to config file + std::ofstream configFile; + configFile.open(prefixCustom + "config.toml"); + configFile << "use_haar = " << (useHaarCheckBox->GetValue() ? "true" : "false") << std::endl; + configFile << "model = \"" << modelNameText->GetValue() << "\""<< std::endl; + configFile.close(); + Close(true); } diff --git a/src/main.cpp b/src/main.cpp index bdf7b58..24579c0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,18 +4,25 @@ #include #include #include +#include #include #include int main (int argc, char** argv) { -#ifndef _WIN32 - argp_parse(&argp, argc, argv, 0, 0, 0); -#endif - std::cout << PROJECT_NAME " is starting..." << std::endl; initPrefixes(); + + // load config file and apply it + configFileOpen(&optData); + +#ifndef _WIN32 + // parse arguments and apply them + argp_parse(&argp, argc, argv, 0, 0, 0); +#endif + + std::cout << "Custom asset prefix: " << prefixCustom << std::endl; std::cout << "Default asset prefix: " << prefixDefault << std::endl; From d18f9d31625ebd2244eebd376dcd613a0d93b207 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Fri, 2 Jul 2021 02:56:39 +0800 Subject: [PATCH 03/11] Change model selection to dropdown menu --- CMakeLists.txt | 1 + src/fc2dconfig.cpp | 25 ++++++++++++++++++++----- src/modellist.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ src/modellist.hpp | 8 ++++++++ 4 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 src/modellist.cpp create mode 100644 src/modellist.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index dcb0eb2..933e81e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,5 +72,6 @@ target_link_libraries( fc2d ${OpenCV_LIBS} ${OPENGL_LIBRARIES} ${WEBP_LIBRARIES} add_executable( fc2dconfig src/fc2dconfig.cpp src/paths.cpp + src/modellist.cpp ) target_link_libraries( fc2dconfig ${wxWidgets_LIBRARIES} ) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index c3ad3ab..199109b 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #ifndef WX_PRECOMP @@ -18,8 +19,9 @@ class ConfigurationFrame : public wxFrame { public: ConfigurationFrame(); private: + std::vector modelVec; wxCheckBox* useHaarCheckBox; - wxTextCtrl* modelNameText; + wxChoice* modelNameChoice; void OnExit(wxCommandEvent& event); }; @@ -41,15 +43,24 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " // TODO: load config file and populate values wxStaticText* placeholderText = new wxStaticText(panel, wxID_ANY, "There's nothing here right now, just click OK."); useHaarCheckBox = new wxCheckBox(panel, wxID_ANY, "Disable DNN face detection"); - // TODO: make this a dropdown with the detected model files - modelNameText = new wxTextCtrl(panel, wxID_ANY, "test"); + + // find models to populate model dropdown + modelVec = listModels(); + wxString modelArray[modelVec.size()]; + + for (int i = 0; i < modelVec.size(); i++) { + modelArray[i] = wxString(modelVec[i]); + } + + modelNameChoice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, modelVec.size(), modelArray); + // TODO: cancel button to exit without saving settings wxButton* okButton = new wxButton(panel, wxID_OK, "OK"); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(placeholderText, 0, wxALL | wxALIGN_LEFT, 10); sizer->Add(useHaarCheckBox, 0, wxALL | wxALIGN_LEFT, 5); - sizer->Add(modelNameText, 0, wxALL | wxALIGN_LEFT, 5); + sizer->Add(modelNameChoice, 0, wxALL | wxALIGN_LEFT, 5); sizer->AddStretchSpacer(1); sizer->Add(okButton, 0, wxALIGN_RIGHT | wxALL, 10); @@ -63,7 +74,11 @@ void ConfigurationFrame::OnExit(wxCommandEvent& event) { std::ofstream configFile; configFile.open(prefixCustom + "config.toml"); configFile << "use_haar = " << (useHaarCheckBox->GetValue() ? "true" : "false") << std::endl; - configFile << "model = \"" << modelNameText->GetValue() << "\""<< std::endl; + // janky edge case lmao + // if user did not select any model, don't write the line in the config file! + if (modelNameChoice->GetSelection() != wxNOT_FOUND) { + configFile << "model = \"" << modelVec[modelNameChoice->GetSelection()] << "\""<< std::endl; + } configFile.close(); Close(true); diff --git a/src/modellist.cpp b/src/modellist.cpp new file mode 100644 index 0000000..59bc692 --- /dev/null +++ b/src/modellist.cpp @@ -0,0 +1,46 @@ +#include + +#include + +#include + +#include + +// get models from a given directory and add them to a given vector +void getModelsFromDir(std::string path, std::vector* vector) { + DIR* dir; + struct dirent* ent; + + if ((dir = opendir(path.c_str())) != NULL) { + while ((ent = readdir(dir)) != NULL) { + std::string filename = ent->d_name; + size_t fmaPos = filename.find(".fma"); // position of ".fma" in filename + + if (fmaPos == std::string::npos) { + // filename does not have ".fma" in it + continue; + } + + filename.erase(fmaPos); + + vector->push_back(filename); + } + closedir(dir); + } +} + +std::vector listModels() { + std::vector modelList; + + getModelsFromDir(prefixCustom + "models", &modelList); + getModelsFromDir(prefixDefault + "models", &modelList); + getModelsFromDir("models", &modelList); + + /* + for (int i = 0; i < modelList.size(); i++) { + std::cout << "Detected model: " << modelList.at(i) << std::endl; + } + */ + + return modelList; +} diff --git a/src/modellist.hpp b/src/modellist.hpp new file mode 100644 index 0000000..ec46d39 --- /dev/null +++ b/src/modellist.hpp @@ -0,0 +1,8 @@ +#ifndef MODELLIST_HPP +#define MODELLIST_HPP + +#include + +std::vector listModels(); + +#endif From dbd3afb6fe5876eb5b122d2a6107a39bb6d0a7e5 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Fri, 2 Jul 2021 03:10:37 +0800 Subject: [PATCH 04/11] Add cancel button and rename OK to apply --- src/fc2dconfig.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index 199109b..9210ed3 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -22,6 +22,7 @@ class ConfigurationFrame : public wxFrame { std::vector modelVec; wxCheckBox* useHaarCheckBox; wxChoice* modelNameChoice; + void OnApply(wxCommandEvent& event); void OnExit(wxCommandEvent& event); }; @@ -55,21 +56,27 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " modelNameChoice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, modelVec.size(), modelArray); // TODO: cancel button to exit without saving settings - wxButton* okButton = new wxButton(panel, wxID_OK, "OK"); + wxButton* cancelButton = new wxButton(panel, wxID_CANCEL, "Cancel"); + wxButton* applyButton = new wxButton(panel, wxID_APPLY, "Apply settings"); + + wxBoxSizer* bottomButtonSizer = new wxBoxSizer(wxHORIZONTAL); + bottomButtonSizer->Add(cancelButton, 0, wxALL, 5); + bottomButtonSizer->Add(applyButton, 0, wxALL, 5); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); sizer->Add(placeholderText, 0, wxALL | wxALIGN_LEFT, 10); sizer->Add(useHaarCheckBox, 0, wxALL | wxALIGN_LEFT, 5); sizer->Add(modelNameChoice, 0, wxALL | wxALIGN_LEFT, 5); sizer->AddStretchSpacer(1); - sizer->Add(okButton, 0, wxALIGN_RIGHT | wxALL, 10); + sizer->Add(bottomButtonSizer, 0, wxALIGN_RIGHT | wxALL, 10); panel->SetSizerAndFit(sizer); - Bind(wxEVT_BUTTON, &ConfigurationFrame::OnExit, this, wxID_OK); + Bind(wxEVT_BUTTON, &ConfigurationFrame::OnApply, this, wxID_APPLY); + Bind(wxEVT_BUTTON, &ConfigurationFrame::OnExit, this, wxID_CANCEL); } -void ConfigurationFrame::OnExit(wxCommandEvent& event) { +void ConfigurationFrame::OnApply(wxCommandEvent& event) { // write options to config file std::ofstream configFile; configFile.open(prefixCustom + "config.toml"); @@ -83,3 +90,7 @@ void ConfigurationFrame::OnExit(wxCommandEvent& event) { Close(true); } + +void ConfigurationFrame::OnExit(wxCommandEvent& event) { + Close(true); +} From 378bcf7f16423b64db0f8ee791444c4f277ec16e Mon Sep 17 00:00:00 2001 From: Epicalert Date: Fri, 2 Jul 2021 03:11:28 +0800 Subject: [PATCH 05/11] Remove unnecessary lines --- src/fc2dconfig.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index 9210ed3..6d86956 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -42,7 +42,6 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " wxPanel* panel = new wxPanel(this, wxID_ANY); // TODO: load config file and populate values - wxStaticText* placeholderText = new wxStaticText(panel, wxID_ANY, "There's nothing here right now, just click OK."); useHaarCheckBox = new wxCheckBox(panel, wxID_ANY, "Disable DNN face detection"); // find models to populate model dropdown @@ -55,7 +54,6 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " modelNameChoice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, modelVec.size(), modelArray); - // TODO: cancel button to exit without saving settings wxButton* cancelButton = new wxButton(panel, wxID_CANCEL, "Cancel"); wxButton* applyButton = new wxButton(panel, wxID_APPLY, "Apply settings"); From e5a1cdd6da69179b7b916274e717daaf060af2a2 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Fri, 2 Jul 2021 03:45:19 +0800 Subject: [PATCH 06/11] Changed config file path Config file is now stored under ~/.config in Linux, and %AppData%\Roaming in Windows. Custom prefix has been changed to %AppData%\Local\Facecam2D in Windows, instead of the improper %AppData%\Facecam2D. MacOS paths remain unchanged. --- src/configfile.cpp | 2 +- src/fc2dconfig.cpp | 3 +-- src/paths.cpp | 11 ++++++++--- src/paths.hpp | 1 + 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/configfile.cpp b/src/configfile.cpp index 9e95d3c..8666627 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -7,7 +7,7 @@ #include bool configFileOpen(struct optData* data) { - auto configFile = toml::parseFile(prefixCustom + "config.toml"); + auto configFile = toml::parseFile(prefixConfig + "config.toml"); if (!configFile.table) { return false; } diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index 6d86956..92c0dda 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -62,7 +62,6 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " bottomButtonSizer->Add(applyButton, 0, wxALL, 5); wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(placeholderText, 0, wxALL | wxALIGN_LEFT, 10); sizer->Add(useHaarCheckBox, 0, wxALL | wxALIGN_LEFT, 5); sizer->Add(modelNameChoice, 0, wxALL | wxALIGN_LEFT, 5); sizer->AddStretchSpacer(1); @@ -77,7 +76,7 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " void ConfigurationFrame::OnApply(wxCommandEvent& event) { // write options to config file std::ofstream configFile; - configFile.open(prefixCustom + "config.toml"); + configFile.open(prefixConfig + "config.toml"); configFile << "use_haar = " << (useHaarCheckBox->GetValue() ? "true" : "false") << std::endl; // janky edge case lmao // if user did not select any model, don't write the line in the config file! diff --git a/src/paths.cpp b/src/paths.cpp index e1ef84c..6969309 100644 --- a/src/paths.cpp +++ b/src/paths.cpp @@ -9,18 +9,23 @@ #define READABLE(p) access(p.c_str(),R_OK)==0 #endif -std::string prefixCustom; -std::string prefixDefault; +std::string prefixConfig; // directory to store config.toml in +std::string prefixCustom; // directory for user-accessible models and cvdata +std::string prefixDefault; // directory for pre-installed models and cvdata void initPrefixes() { #if defined (__gnu_linux__) + prefixConfig = getenv("HOME") + std::string("/.config/facecam2d/"); prefixCustom = getenv("HOME") + std::string("/.local/share/facecam2d/"); prefixDefault = "/usr/share/facecam2d/"; #elif defined (__APPLE__) + // config and supporting files are both stored in Library on MacOS + prefixConfig = getenv("HOME") + std::string("/Library/Facecam2D/"); prefixCustom = getenv("HOME") + std::string("/Library/Facecam2D/"); prefixDefault = "/Applications/Facecam2D.app/"; #elif defined (_WIN32) - prefixCustom = getenv("AppData") + std::string("\\Facecam2D\\"); + prefixConfig = getenv("AppData") + std::string("\\Roaming\\Facecam2D\\"); + prefixCustom = getenv("AppData") + std::string("\\Local\\Facecam2D\\"); prefixDefault = getenv("ProgramFiles") + std::string("\\Facecam2D\\"); #endif } diff --git a/src/paths.hpp b/src/paths.hpp index 31ba82f..71edec5 100644 --- a/src/paths.hpp +++ b/src/paths.hpp @@ -3,6 +3,7 @@ #include +extern std::string prefixConfig; extern std::string prefixCustom; extern std::string prefixDefault; From 3c94c5755873b38ea914537309a1ab11f87cc027 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Fri, 2 Jul 2021 18:25:32 +0800 Subject: [PATCH 07/11] Improve readability of config menu --- src/fc2dconfig.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index 92c0dda..f74f468 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -39,31 +39,43 @@ bool ConfigurationApp::OnInit() { } ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " PROJECT_NAME) { - wxPanel* panel = new wxPanel(this, wxID_ANY); - - // TODO: load config file and populate values - useHaarCheckBox = new wxCheckBox(panel, wxID_ANY, "Disable DNN face detection"); - // find models to populate model dropdown modelVec = listModels(); wxString modelArray[modelVec.size()]; - for (int i = 0; i < modelVec.size(); i++) { modelArray[i] = wxString(modelVec[i]); } + + wxPanel* panel = new wxPanel(this, wxID_ANY); + + // TODO: load config file and populate values + // define all controls and labels + useHaarCheckBox = new wxCheckBox(panel, wxID_ANY, "Disable DNN face detection"); + wxStaticText* modelNameText = new wxStaticText(panel, wxID_ANY, "Model name:"); modelNameChoice = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, modelVec.size(), modelArray); + wxBoxSizer* modelSizer = new wxBoxSizer(wxHORIZONTAL); // need to put label next to dropdown + modelSizer->Add(modelNameText, 0, wxALIGN_CENTER | wxALL, 5); + modelSizer->Add(modelNameChoice, 0, wxLEFT, 20); + + wxStaticBoxSizer* generalBoxSizer = new wxStaticBoxSizer(new wxStaticBox(panel, wxID_ANY, "General"), wxVERTICAL); + generalBoxSizer->Add(modelSizer, 0, wxALL, 5); + + wxStaticBoxSizer* performanceBoxSizer = new wxStaticBoxSizer(new wxStaticBox(panel, wxID_ANY, "Performance"), wxVERTICAL); + performanceBoxSizer->Add(useHaarCheckBox, 0, wxALL, 5); + + // define bottom buttons (Cancel and Apply) and their sizer wxButton* cancelButton = new wxButton(panel, wxID_CANCEL, "Cancel"); wxButton* applyButton = new wxButton(panel, wxID_APPLY, "Apply settings"); - wxBoxSizer* bottomButtonSizer = new wxBoxSizer(wxHORIZONTAL); bottomButtonSizer->Add(cancelButton, 0, wxALL, 5); bottomButtonSizer->Add(applyButton, 0, wxALL, 5); + // define main sizer wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); - sizer->Add(useHaarCheckBox, 0, wxALL | wxALIGN_LEFT, 5); - sizer->Add(modelNameChoice, 0, wxALL | wxALIGN_LEFT, 5); + sizer->Add(generalBoxSizer, 0, wxALL | wxALIGN_LEFT | wxEXPAND, 10); + sizer->Add(performanceBoxSizer, 0, wxALL | wxALIGN_LEFT | wxEXPAND, 10); sizer->AddStretchSpacer(1); sizer->Add(bottomButtonSizer, 0, wxALIGN_RIGHT | wxALL, 10); From 07ccce90d3f9d83c5d2fba2a0c34d564bc565d1a Mon Sep 17 00:00:00 2001 From: Epicalert Date: Fri, 2 Jul 2021 23:40:52 +0800 Subject: [PATCH 08/11] Use std::filesystem instead of dirent.h --- src/modellist.cpp | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/modellist.cpp b/src/modellist.cpp index 59bc692..b39e529 100644 --- a/src/modellist.cpp +++ b/src/modellist.cpp @@ -1,6 +1,5 @@ #include - -#include +#include #include @@ -8,24 +7,14 @@ // get models from a given directory and add them to a given vector void getModelsFromDir(std::string path, std::vector* vector) { - DIR* dir; - struct dirent* ent; + // return if directory doesnt exist + if (!std::filesystem::exists(path)) return; - if ((dir = opendir(path.c_str())) != NULL) { - while ((ent = readdir(dir)) != NULL) { - std::string filename = ent->d_name; - size_t fmaPos = filename.find(".fma"); // position of ".fma" in filename - - if (fmaPos == std::string::npos) { - // filename does not have ".fma" in it - continue; - } - - filename.erase(fmaPos); - - vector->push_back(filename); + // iterate through all items in this directory + for (auto& p: std::filesystem::directory_iterator(path)) { + if (p.path().extension() == ".fma") { + vector->push_back(p.path().stem().string()); } - closedir(dir); } } From b9c9cb3de4d6d4915871479538b18de4db0d4386 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Sat, 3 Jul 2021 00:19:14 +0800 Subject: [PATCH 09/11] Make .local and .config directories on startup Directories for the config file and custom data will be created when Facecam2D starts. --- src/fc2dconfig.cpp | 2 ++ src/main.cpp | 1 + src/paths.cpp | 8 ++++++++ src/paths.hpp | 2 ++ 4 files changed, 13 insertions(+) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index f74f468..f4a6d60 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -30,6 +30,8 @@ wxIMPLEMENT_APP(ConfigurationApp); bool ConfigurationApp::OnInit() { initPrefixes(); + makePaths(); + // TODO: put config file creation here diff --git a/src/main.cpp b/src/main.cpp index 24579c0..71f12d1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,7 @@ int main (int argc, char** argv) { std::cout << PROJECT_NAME " is starting..." << std::endl; initPrefixes(); + makePaths(); // load config file and apply it configFileOpen(&optData); diff --git a/src/paths.cpp b/src/paths.cpp index 6969309..f918821 100644 --- a/src/paths.cpp +++ b/src/paths.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #ifdef _WIN32 @@ -30,6 +31,13 @@ void initPrefixes() { #endif } +void makePaths() { + std::filesystem::create_directories(prefixConfig); + std::filesystem::create_directories(prefixCustom + "models/"); + std::filesystem::create_directories(prefixCustom + "cvdata/"); +} + + std::string resolvePath(const char* path) { std::string customString = prefixCustom + path; std::string defaultString = prefixDefault + path; diff --git a/src/paths.hpp b/src/paths.hpp index 71edec5..0b20ea1 100644 --- a/src/paths.hpp +++ b/src/paths.hpp @@ -9,6 +9,8 @@ extern std::string prefixDefault; void initPrefixes(); +void makePaths(); + std::string resolvePath(const char* path); #endif From 5c53e82fb79139100530c5a30d095d116183b544 Mon Sep 17 00:00:00 2001 From: Epicalert Date: Sat, 3 Jul 2021 00:38:05 +0800 Subject: [PATCH 10/11] Make fc2dconfig read existing config file --- CMakeLists.txt | 3 +++ src/fc2dconfig.cpp | 17 +++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 933e81e..2629358 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,5 +73,8 @@ add_executable( fc2dconfig src/fc2dconfig.cpp src/paths.cpp src/modellist.cpp + src/configfile.cpp + src/toml.c + src/tomlcpp.cpp ) target_link_libraries( fc2dconfig ${wxWidgets_LIBRARIES} ) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index f4a6d60..15ae4a1 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #ifndef WX_PRECOMP @@ -22,6 +23,7 @@ class ConfigurationFrame : public wxFrame { std::vector modelVec; wxCheckBox* useHaarCheckBox; wxChoice* modelNameChoice; + void loadExistingConfig(); // loads existing config file and populates controls void OnApply(wxCommandEvent& event); void OnExit(wxCommandEvent& event); }; @@ -85,6 +87,21 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " Bind(wxEVT_BUTTON, &ConfigurationFrame::OnApply, this, wxID_APPLY); Bind(wxEVT_BUTTON, &ConfigurationFrame::OnExit, this, wxID_CANCEL); + + loadExistingConfig(); +} + +void ConfigurationFrame::loadExistingConfig() { + struct optData configData; + configFileOpen(&configData); + + useHaarCheckBox->SetValue(configData.useHaar); + for (int i = 0; i < modelVec.size(); i++) { + if (modelVec[i] == configData.model) { + modelNameChoice->SetSelection(i); + break; + } + } } void ConfigurationFrame::OnApply(wxCommandEvent& event) { From 4d29b21099cc048e9ceb2ec3920bf47d67c6875b Mon Sep 17 00:00:00 2001 From: Epicalert Date: Sat, 3 Jul 2021 00:39:20 +0800 Subject: [PATCH 11/11] Remove unnecessary TODOs --- src/fc2dconfig.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/fc2dconfig.cpp b/src/fc2dconfig.cpp index 15ae4a1..ed8ded6 100644 --- a/src/fc2dconfig.cpp +++ b/src/fc2dconfig.cpp @@ -34,9 +34,6 @@ bool ConfigurationApp::OnInit() { initPrefixes(); makePaths(); - - // TODO: put config file creation here - ConfigurationFrame* frame = new ConfigurationFrame(); frame->Show(true); return true; @@ -53,7 +50,6 @@ ConfigurationFrame::ConfigurationFrame() : wxFrame(NULL, wxID_ANY, "Configure " wxPanel* panel = new wxPanel(this, wxID_ANY); - // TODO: load config file and populate values // define all controls and labels useHaarCheckBox = new wxCheckBox(panel, wxID_ANY, "Disable DNN face detection"); wxStaticText* modelNameText = new wxStaticText(panel, wxID_ANY, "Model name:");