Implemented view change and trash in file selector, and moved more file IO to SDL file IO
This commit is contained in:
parent
b81b33660e
commit
9ea5a1eae9
15 changed files with 585 additions and 203 deletions
|
|
@ -111,6 +111,7 @@ set(sources "src/main.cpp"
|
|||
"src/GUIStuff/Elements/GUIStuffHelpers.cpp"
|
||||
"src/GUIStuff/Elements/Element.cpp"
|
||||
"src/GUIStuff/Elements/ImageDisplay.cpp"
|
||||
"src/GUIStuff/Elements/MutableTextLabel.cpp"
|
||||
"src/GUIStuff/Elements/SVGIcon.cpp"
|
||||
"src/GUIStuff/Elements/RadioButton.cpp"
|
||||
"src/GUIStuff/Elements/CheckBox.cpp"
|
||||
|
|
|
|||
1
assets/data/icons/RemixIcon/more-2-fill.svg
Normal file
1
assets/data/icons/RemixIcon/more-2-fill.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M12 3C10.9 3 10 3.9 10 5C10 6.1 10.9 7 12 7C13.1 7 14 6.1 14 5C14 3.9 13.1 3 12 3ZM12 17C10.9 17 10 17.9 10 19C10 20.1 10.9 21 12 21C13.1 21 14 20.1 14 19C14 17.9 13.1 17 12 17ZM12 10C10.9 10 10 10.9 10 12C10 13.1 10.9 14 12 14C13.1 14 14 13.1 14 12C14 10.9 13.1 10 12 10Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 376 B |
1
assets/data/icons/RemixIcon/refresh-line.svg
Normal file
1
assets/data/icons/RemixIcon/refresh-line.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M5.46257 4.43262C7.21556 2.91688 9.5007 2 12 2C17.5228 2 22 6.47715 22 12C22 14.1361 21.3302 16.1158 20.1892 17.7406L17 12H20C20 7.58172 16.4183 4 12 4C9.84982 4 7.89777 4.84827 6.46023 6.22842L5.46257 4.43262ZM18.5374 19.5674C16.7844 21.0831 14.4993 22 12 22C6.47715 22 2 17.5228 2 12C2 9.86386 2.66979 7.88416 3.8108 6.25944L7 12H4C4 16.4183 7.58172 20 12 20C14.1502 20 16.1022 19.1517 17.5398 17.7716L18.5374 19.5674Z"></path></svg>
|
||||
|
After Width: | Height: | Size: 524 B |
|
|
@ -1,5 +1,4 @@
|
|||
#include "NetLibrary.hpp"
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <rtc/peerconnection.hpp>
|
||||
#include "../Logger.hpp"
|
||||
|
|
@ -175,29 +174,23 @@ void NetLibrary::init(const std::filesystem::path& p2pConfigPath) {
|
|||
}
|
||||
|
||||
void NetLibrary::copy_default_p2p_config_to_path(const std::filesystem::path& newP2PConfigPath) {
|
||||
std::ifstream checkIfFileAlreadyExists(newP2PConfigPath);
|
||||
if(checkIfFileAlreadyExists.is_open()) { // Don't copy if P2P config exists already
|
||||
try {
|
||||
std::string readLocalP2PConfig = read_file_to_string(newP2PConfigPath); // If it doesnt fail, then file exists, so dont copy p2p config
|
||||
Logger::get().log("INFO", "Local P2P configuration already exists");
|
||||
checkIfFileAlreadyExists.close();
|
||||
return;
|
||||
}
|
||||
std::ifstream defaultP2PConfig("data/config/default_p2p.json");
|
||||
if(defaultP2PConfig.is_open()) {
|
||||
nlohmann::json j;
|
||||
defaultP2PConfig >> j;
|
||||
defaultP2PConfig.close();
|
||||
} catch(...) {}
|
||||
|
||||
std::ofstream newFile(newP2PConfigPath);
|
||||
if(newFile.is_open()) {
|
||||
newFile << std::setw(4) << j;
|
||||
newFile.close();
|
||||
try {
|
||||
nlohmann::json j(nlohmann::json::parse(read_file_to_string("data/config/default_p2p.json")));
|
||||
std::stringstream newFileSS;
|
||||
newFileSS << std::setw(4) << j;
|
||||
if(SDL_SaveFile(newP2PConfigPath.string().c_str(), newFileSS.view().data(), newFileSS.view().size()))
|
||||
Logger::get().log("INFO", "New P2P configuration created");
|
||||
}
|
||||
else
|
||||
Logger::get().log("INFO", "[NetLibrary::copy_default_p2p_config_to_path] Could not open new p2p.json to write to");
|
||||
}
|
||||
else
|
||||
} catch(...) {
|
||||
Logger::get().log("INFO", "[NetLibrary::copy_default_p2p_config_to_path] Could not open default_p2p.json");
|
||||
}
|
||||
}
|
||||
|
||||
std::string NetLibrary::get_random_server_local_id() {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "TextLabelHelpers.hpp"
|
||||
#include "../Elements/MutableTextLabel.hpp"
|
||||
|
||||
namespace GUIStuff { namespace ElementHelpers {
|
||||
|
||||
|
|
@ -40,4 +41,8 @@ void text_label_light_centered(GUIManager& gui, std::string_view val) {
|
|||
}
|
||||
}
|
||||
|
||||
void mutable_text_label(GUIManager& gui, const char* id, const std::string& val) {
|
||||
gui.element<MutableTextLabel>(id, val, CLAY_TEXT_CONFIG({.textColor = convert_vec4<Clay_Color>(gui.io.theme->frontColor1), .fontSize = gui.io.fontSize }));
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -10,4 +10,6 @@ void text_label(GUIManager& gui, std::string_view val);
|
|||
void text_label_light_centered(GUIManager& gui, std::string_view val);
|
||||
void text_label_centered(GUIManager& gui, std::string_view val);
|
||||
|
||||
void mutable_text_label(GUIManager& gui, const char* id, const std::string& val);
|
||||
|
||||
}}
|
||||
|
|
|
|||
20
src/GUIStuff/Elements/MutableTextLabel.cpp
Normal file
20
src/GUIStuff/Elements/MutableTextLabel.cpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "MutableTextLabel.hpp"
|
||||
#include "../GUIManager.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
MutableTextLabel::MutableTextLabel(GUIManager& gui): Element(gui) {}
|
||||
|
||||
void MutableTextLabel::layout(const Clay_ElementId& id, const std::string& text, Clay_TextElementConfig* textConfig) {
|
||||
if(text != oldText) {
|
||||
oldText = text;
|
||||
gui.invalidate_draw_element(this);
|
||||
}
|
||||
CLAY(id, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)}}
|
||||
}) {
|
||||
CLAY_TEXT(gui.strArena.std_str_to_clay_str(text), textConfig);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
15
src/GUIStuff/Elements/MutableTextLabel.hpp
Normal file
15
src/GUIStuff/Elements/MutableTextLabel.hpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
class MutableTextLabel : public Element {
|
||||
public:
|
||||
MutableTextLabel(GUIManager& gui);
|
||||
void layout(const Clay_ElementId& id, const std::string& text, Clay_TextElementConfig* textConfig);
|
||||
private:
|
||||
std::string oldText;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -17,15 +17,6 @@ void PositionAdjustingPopupMenu::layout(const Clay_ElementId& id, Vector2f popup
|
|||
|
||||
layoutElement = gui.element<LayoutElement>("popup", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(100), .height = CLAY_SIZING_FIT(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = 1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(gui.io.theme->windowCorners1),
|
||||
.floating = {
|
||||
.offset = {popupPos.x(), popupPos.y()},
|
||||
.zIndex = gui.get_z_index(),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "GlobalConfig.hpp"
|
||||
#include <Helpers/Random.hpp>
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include "ResourceDisplay/ImageResourceDisplay.hpp"
|
||||
#include "DrawingProgram/DrawingProgramCache.hpp"
|
||||
#include <SDL3/SDL_time.h>
|
||||
|
|
@ -132,32 +133,25 @@ void GlobalConfig::set_config_json(InputManager& input, const nlohmann::json& j,
|
|||
}
|
||||
|
||||
void GlobalConfig::save_palettes() {
|
||||
std::ofstream f(configPath / "palettes.json");
|
||||
if(f.is_open()) {
|
||||
using json = nlohmann::json;
|
||||
json j;
|
||||
auto palettesToSave = palettes;
|
||||
palettesToSave.erase(palettesToSave.begin());
|
||||
j = palettesToSave;
|
||||
f << j;
|
||||
f.close();
|
||||
}
|
||||
using json = nlohmann::json;
|
||||
json j;
|
||||
auto palettesToSave = palettes;
|
||||
palettesToSave.erase(palettesToSave.begin());
|
||||
nlohmann::to_json(j, palettesToSave);
|
||||
std::stringstream f;
|
||||
f << j;
|
||||
SDL_SaveFile((configPath / "palettes.json").string().c_str(), f.view().data(), f.view().size());
|
||||
}
|
||||
|
||||
void GlobalConfig::load_palettes() {
|
||||
std::ifstream f(configPath / "palettes.json");
|
||||
load_default_palette();
|
||||
if(f.is_open()) {
|
||||
using json = nlohmann::json;
|
||||
try {
|
||||
json j;
|
||||
f >> j;
|
||||
std::vector<Palette> palettes;
|
||||
j.get_to(palettes);
|
||||
palettes.insert(palettes.end(), palettes.begin(), palettes.end());
|
||||
} catch(...) {}
|
||||
f.close();
|
||||
}
|
||||
using json = nlohmann::json;
|
||||
try {
|
||||
json j(nlohmann::json::parse(read_file_to_string(configPath / "palettes.json")));
|
||||
std::vector<Palette> palettes;
|
||||
j.get_to(palettes);
|
||||
palettes.insert(palettes.end(), palettes.begin(), palettes.end());
|
||||
} catch(...) {}
|
||||
}
|
||||
|
||||
void GlobalConfig::load_default_palette() {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ MainProgram::MainProgram():
|
|||
fonts(std::make_shared<FontData>()),
|
||||
g(*this)
|
||||
{
|
||||
screen = std::make_unique<FileSelectScreen>(*this);
|
||||
Logger::get().add_log("WORLDFATAL", [&](const std::string& text) {
|
||||
*logFile << "[WORLDFATAL] " << text << std::endl;
|
||||
std::cout << "[WORLDFATAL] " << text << std::endl;
|
||||
|
|
@ -95,74 +94,67 @@ void MainProgram::init_net_library() {
|
|||
}
|
||||
|
||||
void MainProgram::save_config() {
|
||||
std::ofstream f(conf.configPath / "config.json");
|
||||
if(f.is_open()) {
|
||||
using json = nlohmann::json;
|
||||
json j;
|
||||
using json = nlohmann::json;
|
||||
json j;
|
||||
|
||||
j["version"] = VersionConstants::CURRENT_VERSION_STRING;
|
||||
j["settings"] = conf.get_config_json(input);
|
||||
j["window"]["pos"] = window.writtenPos;
|
||||
j["window"]["size"] = window.writtenSize;
|
||||
j["window"]["maximized"] = window.maximized;
|
||||
j["window"]["fullscreen"] = window.fullscreen;
|
||||
j["fileselectorpath"] = conf.currentSearchPath;
|
||||
j["toolConfig"] = toolConfig;
|
||||
j["version"] = VersionConstants::CURRENT_VERSION_STRING;
|
||||
j["settings"] = conf.get_config_json(input);
|
||||
j["window"]["pos"] = window.writtenPos;
|
||||
j["window"]["size"] = window.writtenSize;
|
||||
j["window"]["maximized"] = window.maximized;
|
||||
j["window"]["fullscreen"] = window.fullscreen;
|
||||
j["fileselectorpath"] = conf.currentSearchPath;
|
||||
j["toolConfig"] = toolConfig;
|
||||
|
||||
f << std::setw(4) << j;
|
||||
f.close();
|
||||
}
|
||||
std::stringstream f;
|
||||
f << std::setw(4) << j;
|
||||
SDL_SaveFile((conf.configPath / "config.json").string().c_str(), f.view().data(), f.view().size());
|
||||
conf.save_palettes();
|
||||
}
|
||||
|
||||
void MainProgram::load_config() {
|
||||
std::ifstream f(conf.configPath / "config.json");
|
||||
conf.currentSearchPath = homePath;
|
||||
if(f.is_open()) {
|
||||
using json = nlohmann::json;
|
||||
using json = nlohmann::json;
|
||||
|
||||
try {
|
||||
json j(nlohmann::json::parse(read_file_to_string(conf.configPath / "config.json")));
|
||||
|
||||
VersionNumber version(0, 0, 1);
|
||||
try {
|
||||
std::string versionStr;
|
||||
j.at("version").get_to(versionStr);
|
||||
auto optVersion = version_str_to_version_numbers(versionStr);
|
||||
if(optVersion.has_value())
|
||||
version = optVersion.value();
|
||||
}
|
||||
catch(...) {}
|
||||
|
||||
try {
|
||||
json j;
|
||||
f >> j;
|
||||
|
||||
VersionNumber version(0, 0, 1);
|
||||
try {
|
||||
std::string versionStr;
|
||||
j.at("version").get_to(versionStr);
|
||||
auto optVersion = version_str_to_version_numbers(versionStr);
|
||||
if(optVersion.has_value())
|
||||
version = optVersion.value();
|
||||
}
|
||||
catch(...) {}
|
||||
|
||||
try {
|
||||
conf.set_config_json(input, j["settings"], version);
|
||||
}
|
||||
catch(...) {}
|
||||
conf.set_config_json(input, j["settings"], version);
|
||||
}
|
||||
catch(...) {}
|
||||
#ifndef __EMSCRIPTEN__
|
||||
try {
|
||||
j.at("window").at("size").get_to(window.size);
|
||||
window.writtenSize = window.size;
|
||||
j.at("window").at("pos").get_to(window.pos);
|
||||
window.writtenPos = window.pos;
|
||||
j.at("window").at("maximized").get_to(window.maximized);
|
||||
j.at("window").at("fullscreen").get_to(window.fullscreen);
|
||||
}
|
||||
catch(...) {}
|
||||
try {
|
||||
j.at("fileselectorpath").get_to(conf.currentSearchPath);
|
||||
}
|
||||
catch(...) {
|
||||
conf.currentSearchPath = homePath;
|
||||
}
|
||||
try {
|
||||
j.at("window").at("size").get_to(window.size);
|
||||
window.writtenSize = window.size;
|
||||
j.at("window").at("pos").get_to(window.pos);
|
||||
window.writtenPos = window.pos;
|
||||
j.at("window").at("maximized").get_to(window.maximized);
|
||||
j.at("window").at("fullscreen").get_to(window.fullscreen);
|
||||
}
|
||||
catch(...) {}
|
||||
try {
|
||||
j.at("fileselectorpath").get_to(conf.currentSearchPath);
|
||||
}
|
||||
catch(...) {
|
||||
conf.currentSearchPath = homePath;
|
||||
}
|
||||
#endif
|
||||
try {
|
||||
j.at("toolConfig").get_to(toolConfig);
|
||||
}
|
||||
catch(...) {}
|
||||
f.close();
|
||||
} catch(...) {}
|
||||
}
|
||||
try {
|
||||
j.at("toolConfig").get_to(toolConfig);
|
||||
}
|
||||
catch(...) {}
|
||||
} catch(...) {}
|
||||
#ifdef __EMSCRIPTEN__
|
||||
else
|
||||
conf.viewWebVersionWelcome = true;
|
||||
|
|
@ -465,5 +457,6 @@ void MainProgram::early_destroy() {
|
|||
}
|
||||
|
||||
MainProgram::~MainProgram() {
|
||||
screen = nullptr; // Destroy screen first to let destructor run
|
||||
NetLibrary::destroy();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@
|
|||
#include "../GUIStuff/Elements/GridScrollArea.hpp"
|
||||
#include "../GUIStuff/Elements/ImageDisplay.hpp"
|
||||
#include "../GUIStuff/Elements/LayoutElement.hpp"
|
||||
#include "../GUIStuff/Elements/SVGIcon.hpp"
|
||||
#include "../GUIStuff/Elements/PositionAdjustingPopupMenu.hpp"
|
||||
#include "../World.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include "DrawingProgramScreen.hpp"
|
||||
#include <SDL3/SDL_time.h>
|
||||
#include <SDL3/SDL_timer.h>
|
||||
|
||||
#define MAIN_MENU_SIZE 300
|
||||
|
|
@ -17,9 +20,94 @@
|
|||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
FileSelectScreen::FileSelectScreen(MainProgram& m): Screen(m) {}
|
||||
FileSelectScreen::FileSelectScreen(MainProgram& m): Screen(m) {
|
||||
savePath = main.conf.configPath / "saves";
|
||||
trashPath = main.conf.configPath / "trash";
|
||||
trashInfoPath = main.conf.configPath / "trashInfo.json";
|
||||
|
||||
try {
|
||||
nlohmann::json j(nlohmann::json::parse(read_file_to_string(trashInfoPath)));
|
||||
j.get_to(trashInfo);
|
||||
}
|
||||
catch(...) {}
|
||||
|
||||
update_file_list(fileList, savePath, false);
|
||||
|
||||
// Update trash list once to get trash info up to date
|
||||
std::vector<FileInfo> trashListTemp;
|
||||
update_file_list(trashListTemp, trashPath, true);
|
||||
}
|
||||
|
||||
void FileSelectScreen::gui_layout_run() {
|
||||
main_display();
|
||||
}
|
||||
|
||||
void FileSelectScreen::update_file_list(std::vector<FileInfo>& fL, const std::filesystem::path& savePath, bool trashUpdate) {
|
||||
constexpr SDL_Time NS_IN_DAY = SDL_SECONDS_TO_NS(24 * 3600);
|
||||
|
||||
SDL_Time currentTime;
|
||||
SDL_GetCurrentTime(¤tTime);
|
||||
|
||||
SDL_Time afterThirtyDays = currentTime + NS_IN_DAY * 30;
|
||||
|
||||
fL.clear();
|
||||
int globCount;
|
||||
char** filesInPath = SDL_GlobDirectory(savePath.string().c_str(), "*", 0, &globCount);
|
||||
if(filesInPath) {
|
||||
for(int i = 0; i < globCount; i++) {
|
||||
std::filesystem::path p = filesInPath[i];
|
||||
std::string fExt = p.extension().string();
|
||||
if(fExt == "." + World::FILE_EXTENSION) {
|
||||
std::filesystem::path fullPath = savePath / filesInPath[i];
|
||||
FileInfo fileInfoToAdd;
|
||||
fileInfoToAdd.fileName = p.stem().string();
|
||||
|
||||
if(trashUpdate) {
|
||||
auto it = trashInfo.files.find(fileInfoToAdd.fileName);
|
||||
if(it == trashInfo.files.end()) {
|
||||
trashInfo.files[fileInfoToAdd.fileName].trashTime = currentTime;
|
||||
fileInfoToAdd.lastModifyTime = currentTime;
|
||||
}
|
||||
else
|
||||
fileInfoToAdd.lastModifyTime = it->second.trashTime;
|
||||
|
||||
if(fileInfoToAdd.lastModifyTime >= afterThirtyDays) {
|
||||
// Remove file and thumbnail
|
||||
SDL_RemovePath(fullPath.string().c_str());
|
||||
SDL_RemovePath((savePath / fileInfoToAdd.fileName / ".jpg").string().c_str());
|
||||
trashInfo.files.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
int64_t daysToDeletion = (afterThirtyDays - fileInfoToAdd.lastModifyTime) / NS_IN_DAY;
|
||||
|
||||
if(daysToDeletion == 0)
|
||||
fileInfoToAdd.lastModifyDate = "Today";
|
||||
else if(daysToDeletion == 1)
|
||||
fileInfoToAdd.lastModifyDate = "Tomorrow";
|
||||
else
|
||||
fileInfoToAdd.lastModifyDate = std::to_string(daysToDeletion) + " days";
|
||||
}
|
||||
else {
|
||||
SDL_PathInfo pathInfo;
|
||||
if(SDL_GetPathInfo(fullPath.string().c_str(), &pathInfo)) {
|
||||
SDL_DateTime pathDt;
|
||||
fileInfoToAdd.lastModifyTime = pathInfo.modify_time;
|
||||
if(SDL_TimeToDateTime(pathInfo.modify_time, &pathDt, true)) {
|
||||
fileInfoToAdd.lastModifyDate = sdl_time_to_nice_access_time(pathDt, main.conf.dateFormat, main.conf.timeFormat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fL.emplace_back(fileInfoToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
SDL_CreateDirectory(savePath.string().c_str());
|
||||
}
|
||||
|
||||
void FileSelectScreen::main_display() {
|
||||
auto& gui = main.g.gui;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
|
|
@ -33,26 +121,39 @@ void FileSelectScreen::gui_layout_run() {
|
|||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(gui.io.windowSize.x()), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
}) {
|
||||
switch(selectedMenu) {
|
||||
case SelectedMenu::FILES:
|
||||
title_bar("Files");
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::TRASH:
|
||||
title_bar("Trash");
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::SETTINGS:
|
||||
title_bar("Settings");
|
||||
break;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
}) {
|
||||
if(editMode) {
|
||||
numberOfSelectedEntries = std::count_if(fileList.begin(), fileList.end(), [] (const FileInfo& f) { return f.selected; });
|
||||
edit_title_bar();
|
||||
}
|
||||
else
|
||||
title_bar();
|
||||
switch(selectedMenu) {
|
||||
case SelectedMenu::FILES:
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::TRASH:
|
||||
file_view();
|
||||
break;
|
||||
case SelectedMenu::SETTINGS:
|
||||
break;
|
||||
}
|
||||
menu_black_box();
|
||||
}
|
||||
menu_black_box();
|
||||
if(editMode && numberOfSelectedEntries != 0)
|
||||
edit_action_bar();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -62,11 +163,147 @@ bool FileSelectScreen::main_menu_fills_screen() {
|
|||
return main.g.gui.io.windowSize.x() < MAIN_MENU_SIZE + 50;
|
||||
}
|
||||
|
||||
void FileSelectScreen::title_bar(std::string_view title) {
|
||||
void FileSelectScreen::edit_action_bar_button(const char* id, const std::string& svgPath, const char* text, const std::function<void()>& onClick) {
|
||||
auto& gui = main.g.gui;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_FIXED(70), .height = CLAY_SIZING_GROW(0)}}
|
||||
}) {
|
||||
gui.element<SelectableButton>(id, SelectableButton::Data{
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.onClick = onClick,
|
||||
.innerContent = [&](const SelectableButton::InnerContentCallbackParameters&) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_TOP },
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
}
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_FIXED(20), .height = CLAY_SIZING_FIXED(20)}}
|
||||
}) {
|
||||
gui.element<SVGIcon>("icon", svgPath, false);
|
||||
}
|
||||
text_label(gui, text);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::move_selected_files(const std::filesystem::path& fromPath, const std::filesystem::path& toPath, TrashMoveType trashMoveType) {
|
||||
SDL_Time currentTime;
|
||||
SDL_GetCurrentTime(¤tTime);
|
||||
|
||||
std::vector<std::string> toFolderListNames;
|
||||
|
||||
int globCount;
|
||||
char** filesInPath = SDL_GlobDirectory(toPath.c_str(), "*", 0, &globCount);
|
||||
if(filesInPath) {
|
||||
for(int i = 0; i < globCount; i++) {
|
||||
std::filesystem::path p(filesInPath[i]);
|
||||
toFolderListNames.emplace_back(p.filename().stem());
|
||||
}
|
||||
}
|
||||
else
|
||||
SDL_CreateDirectory(toPath.string().c_str());
|
||||
|
||||
for(const FileInfo& f : fileList) {
|
||||
if(f.selected) {
|
||||
std::string newFileName = ensure_string_unique(toFolderListNames, f.fileName);
|
||||
std::filesystem::path filePath = fromPath / (f.fileName + "." + World::FILE_EXTENSION);
|
||||
std::filesystem::path thumbnailPath = fromPath / (f.fileName + ".jpg");
|
||||
std::filesystem::path newFilePath = toPath / (newFileName + "." + World::FILE_EXTENSION);
|
||||
std::filesystem::path newThumbnailPath = toPath / (newFileName + ".jpg");
|
||||
SDL_RenamePath(filePath.string().c_str(), newFilePath.string().c_str());
|
||||
SDL_RenamePath(thumbnailPath.string().c_str(), newThumbnailPath.string().c_str());
|
||||
switch(trashMoveType) {
|
||||
case TrashMoveType::NONE:
|
||||
break;
|
||||
case TrashMoveType::MOVE_TO_TRASH:
|
||||
trashInfo.files[newFileName] = TrashInfo::TrashFile{
|
||||
.trashTime = currentTime
|
||||
};
|
||||
break;
|
||||
case TrashMoveType::MOVE_OUT_OF_TRASH:
|
||||
trashInfo.files.erase(f.fileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::delete_selected_files_in_trash() {
|
||||
for(const FileInfo& f : fileList) {
|
||||
if(f.selected) {
|
||||
std::filesystem::path filePath = trashPath / (f.fileName + World::DOT_FILE_EXTENSION);
|
||||
std::filesystem::path thumbnailPath = trashPath / (f.fileName + ".jpg");
|
||||
SDL_RemovePath(filePath.string().c_str());
|
||||
SDL_RemovePath(thumbnailPath.string().c_str());
|
||||
trashInfo.files.erase(f.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::edit_action_bar() {
|
||||
auto& gui = main.g.gui;
|
||||
gui.element<LayoutElement>("edit action bar", [&](LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_CENTER, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor2),
|
||||
}) {
|
||||
if(selectedMenu == SelectedMenu::FILES) {
|
||||
edit_action_bar_button("trash", "data/icons/trash.svg", "Trash", [&] {
|
||||
move_selected_files(savePath, trashPath, TrashMoveType::MOVE_TO_TRASH);
|
||||
update_file_list(fileList, savePath, false);
|
||||
editMode = false;
|
||||
});
|
||||
}
|
||||
else if(selectedMenu == SelectedMenu::TRASH) {
|
||||
edit_action_bar_button("restore", "data/icons/RemixIcon/refresh-line.svg", "Restore", [&] {
|
||||
move_selected_files(trashPath, savePath, TrashMoveType::MOVE_OUT_OF_TRASH);
|
||||
update_file_list(fileList, trashPath, true);
|
||||
editMode = false;
|
||||
});
|
||||
edit_action_bar_button("delete", "data/icons/trash.svg", "Delete", [&] {
|
||||
delete_selected_files_in_trash();
|
||||
update_file_list(fileList, trashPath, true);
|
||||
editMode = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void FileSelectScreen::edit_title_bar() {
|
||||
auto& gui = main.g.gui;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(40)},
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
}
|
||||
}) {
|
||||
svg_icon_button(gui, "close edit mode button", "data/icons/close.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.onClick = [&] {
|
||||
editMode = false;
|
||||
}
|
||||
});
|
||||
mutable_text_label(gui, "select files label", (numberOfSelectedEntries == 0) ? "Select files" : (std::to_string(numberOfSelectedEntries) + " selected"));
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::title_bar() {
|
||||
auto& gui = main.g.gui;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childAlignment = { .x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER },
|
||||
.layoutDirection = CLAY_LEFT_TO_RIGHT,
|
||||
|
|
@ -78,10 +315,99 @@ void FileSelectScreen::title_bar(std::string_view title) {
|
|||
mainMenuOpen = true;
|
||||
}
|
||||
});
|
||||
text_label(gui, title);
|
||||
switch(selectedMenu) {
|
||||
case SelectedMenu::FILES:
|
||||
mutable_text_label(gui, "main screen header text", "Files");
|
||||
break;
|
||||
case SelectedMenu::TRASH:
|
||||
mutable_text_label(gui, "main screen header text", "Trash");
|
||||
break;
|
||||
case SelectedMenu::SETTINGS:
|
||||
mutable_text_label(gui, "main screen header text", "Settings");
|
||||
break;
|
||||
}
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)},
|
||||
}
|
||||
}) {}
|
||||
if(selectedMenu == SelectedMenu::FILES || selectedMenu == SelectedMenu::TRASH) {
|
||||
SelectableButton* moreButton = svg_icon_button(gui, "more settings button", "data/icons/RemixIcon/more-2-fill.svg", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.onClick = [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::MAIN;
|
||||
}
|
||||
});
|
||||
if(moreButton->get_bb().has_value() && moreOptionsMenu != MoreOptionsMenu::CLOSED) {
|
||||
gui.set_z_index(gui.get_z_index() + 10, [&] {
|
||||
gui.element<PositionAdjustingPopupMenu>("more options popup", moreButton->get_bb().value().top_right(), [&] {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIT(200), .height = CLAY_SIZING_FIT(0)},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor2),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4)
|
||||
}) {
|
||||
if(moreOptionsMenu == MoreOptionsMenu::MAIN) {
|
||||
text_transparent_option_button("Edit", "Edit", [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
start_edit_mode();
|
||||
});
|
||||
text_transparent_option_button("View", "View", [&] {
|
||||
moreOptionsMenu = MoreOptionsMenu::VIEW;
|
||||
});
|
||||
}
|
||||
else if(moreOptionsMenu == MoreOptionsMenu::VIEW) {
|
||||
text_transparent_option_button("Large Grid", "Large Grid", [&] {
|
||||
fileViewType = FileViewType::LARGE_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
text_transparent_option_button("Medium Grid", "Medium Grid", [&] {
|
||||
fileViewType = FileViewType::MEDIUM_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
text_transparent_option_button("Small Grid", "Small Grid", [&] {
|
||||
fileViewType = FileViewType::SMALL_GRID;
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
});
|
||||
}
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseButton = [&](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& m) {
|
||||
if(!l->mouseHovering && m.down) {
|
||||
moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
main.g.gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileSelectScreen::text_transparent_option_button(const char* id, const char* text, const std::function<void()>& onClick) {
|
||||
auto& gui = main.g.gui;
|
||||
text_button(gui, id, text, {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = onClick
|
||||
});
|
||||
}
|
||||
|
||||
void FileSelectScreen::icon_text_transparent_option_selected_button(const char* id, const std::string& svgPath, const char* text, bool isSelected, const std::function<void()>& onClick) {
|
||||
auto& gui = main.g.gui;
|
||||
text_button_with_icon(gui, id, svgPath, text, {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = isSelected,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = onClick
|
||||
});
|
||||
}
|
||||
|
||||
void FileSelectScreen::main_menu() {
|
||||
auto& gui = main.g.gui;
|
||||
gui.element<LayoutElement>("main menu popup", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
|
|
@ -89,41 +415,23 @@ void FileSelectScreen::main_menu() {
|
|||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(static_cast<float>(main_menu_fills_screen() ? 0 : 300)), .height = CLAY_SIZING_GROW(0)},
|
||||
.padding = CLAY_PADDING_ALL(gui.io.theme->padding1),
|
||||
.childGap = gui.io.theme->childGap1,
|
||||
.childGap = 0,
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM,
|
||||
},
|
||||
}) {
|
||||
text_button_with_icon(gui, "Files", "data/icons/folder.svg", "Files", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = selectedMenu == SelectedMenu::FILES,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = [&] {
|
||||
selectedMenu = SelectedMenu::FILES;
|
||||
fileListOptional.reset();
|
||||
mainMenuOpen = false;
|
||||
}
|
||||
icon_text_transparent_option_selected_button("Files", "data/icons/folder.svg", "Files", selectedMenu == SelectedMenu::FILES, [&] {
|
||||
selectedMenu = SelectedMenu::FILES;
|
||||
update_file_list(fileList, savePath, false);
|
||||
mainMenuOpen = false;
|
||||
});
|
||||
text_button_with_icon(gui, "Trash", "data/icons/trash.svg", "Trash", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = selectedMenu == SelectedMenu::TRASH,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = [&] {
|
||||
selectedMenu = SelectedMenu::TRASH;
|
||||
fileListOptional.reset();
|
||||
mainMenuOpen = false;
|
||||
}
|
||||
icon_text_transparent_option_selected_button("Trash", "data/icons/trash.svg", "Trash", selectedMenu == SelectedMenu::TRASH, [&] {
|
||||
selectedMenu = SelectedMenu::TRASH;
|
||||
update_file_list(fileList, trashPath, true);
|
||||
mainMenuOpen = false;
|
||||
});
|
||||
text_button_with_icon(gui, "Settings", "data/icons/RemixIcon/settings-3-line.svg", "Settings", {
|
||||
.drawType = SelectableButton::DrawType::TRANSPARENT_ALL,
|
||||
.isSelected = selectedMenu == SelectedMenu::SETTINGS,
|
||||
.wide = true,
|
||||
.centered = false,
|
||||
.onClick = [&] {
|
||||
selectedMenu = SelectedMenu::SETTINGS;
|
||||
mainMenuOpen = false;
|
||||
}
|
||||
icon_text_transparent_option_selected_button("Settings", "data/icons/RemixIcon/settings-3-line.svg", "Settings", selectedMenu == SelectedMenu::SETTINGS, [&] {
|
||||
selectedMenu = SelectedMenu::SETTINGS;
|
||||
mainMenuOpen = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -131,22 +439,43 @@ void FileSelectScreen::main_menu() {
|
|||
|
||||
void FileSelectScreen::file_view() {
|
||||
auto& gui = main.g.gui;
|
||||
bool isTrash = selectedMenu == SelectedMenu::TRASH;
|
||||
std::string folder = isTrash ? "trash" : "saves";
|
||||
auto& fileList = get_file_list(folder);
|
||||
std::filesystem::path folderPath = (selectedMenu == SelectedMenu::TRASH) ? trashPath : savePath;
|
||||
|
||||
Vector2f entrySize{0.0f, 0.0f};
|
||||
Vector2f iconSize{0.0f, 0.0f};
|
||||
switch(fileViewType) {
|
||||
case FileViewType::LARGE_GRID:
|
||||
entrySize = {200.0f, 220.0f};
|
||||
iconSize = {150.0f, 150.0f};
|
||||
break;
|
||||
case FileViewType::MEDIUM_GRID:
|
||||
entrySize = {170.0f, 190.0f};
|
||||
iconSize = {120.0f, 120.0f};
|
||||
break;
|
||||
case FileViewType::SMALL_GRID:
|
||||
entrySize = {140.0f, 160.0f};
|
||||
iconSize = {90.0f, 90.0f};
|
||||
break;
|
||||
}
|
||||
|
||||
gui.element<GridScrollArea>("File selector grid", GridScrollArea::Options{
|
||||
.entryWidth = 180.0f,
|
||||
.entryWidth = entrySize.x(),
|
||||
.childAlignmentX = CLAY_ALIGN_X_LEFT,
|
||||
.entryHeight = 200.0f,
|
||||
.entryHeight = entrySize.y(),
|
||||
.entryCount = fileList.size(),
|
||||
.elementContent = [&](size_t i) {
|
||||
std::filesystem::path filePath = main.conf.configPath / folder / (fileList[i].fileName + ".infpnt");
|
||||
std::filesystem::path filePath = folderPath / (fileList[i].fileName + "." + World::FILE_EXTENSION);
|
||||
gui.element<SelectableButton>("file button", SelectableButton::Data{
|
||||
.onClick = [&, filePath] {
|
||||
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
|
||||
.isClient = false,
|
||||
.filePathSource = filePath
|
||||
});
|
||||
.isSelected = editMode && fileList[i].selected,
|
||||
.onClick = [&, filePath, i] {
|
||||
if(editMode)
|
||||
fileList[i].selected = !fileList[i].selected;
|
||||
else {
|
||||
CustomEvents::emit_event<CustomEvents::OpenInfiniPaintFileEvent>({
|
||||
.isClient = false,
|
||||
.filePathSource = filePath
|
||||
});
|
||||
}
|
||||
},
|
||||
.innerContent = [&](const SelectableButton::InnerContentCallbackParameters& c){
|
||||
CLAY_AUTO_ID({
|
||||
|
|
@ -159,10 +488,10 @@ void FileSelectScreen::file_view() {
|
|||
}
|
||||
}) {
|
||||
CLAY_AUTO_ID({
|
||||
.layout = { .sizing = {.width = CLAY_SIZING_FIXED(130), .height = CLAY_SIZING_FIXED(130) }},
|
||||
.layout = { .sizing = {.width = CLAY_SIZING_FIXED(iconSize.x()), .height = CLAY_SIZING_FIXED(iconSize.y()) }},
|
||||
}) {
|
||||
gui.element<ImageDisplay>("ico", ImageDisplay::Data{
|
||||
.imgPath = main.conf.configPath / folder / (fileList[i].fileName + ".jpg"),
|
||||
.imgPath = folderPath / (fileList[i].fileName + ".jpg"),
|
||||
.radius = 20
|
||||
});
|
||||
}
|
||||
|
|
@ -207,37 +536,10 @@ void FileSelectScreen::menu_black_box() {
|
|||
}
|
||||
}
|
||||
|
||||
const std::vector<FileSelectScreen::FileInfo>& FileSelectScreen::get_file_list(const std::string& folder) {
|
||||
if(!fileListOptional.has_value()) {
|
||||
std::filesystem::path savePath = main.conf.configPath / folder;
|
||||
fileListOptional = std::vector<FileInfo>();
|
||||
auto& fL = fileListOptional.value();
|
||||
int globCount;
|
||||
char** filesInPath = SDL_GlobDirectory(savePath.string().c_str(), "*", 0, &globCount);
|
||||
if(filesInPath) {
|
||||
for(int i = 0; i < globCount; i++) {
|
||||
std::filesystem::path p = filesInPath[i];
|
||||
std::string fExt = p.extension().string();
|
||||
if(fExt == "." + World::FILE_EXTENSION) {
|
||||
std::filesystem::path fullPath = savePath / filesInPath[i];
|
||||
FileInfo fileInfoToAdd;
|
||||
fileInfoToAdd.fileName = p.stem().string();
|
||||
|
||||
SDL_PathInfo pathInfo;
|
||||
if(SDL_GetPathInfo(fullPath.string().c_str(), &pathInfo)) {
|
||||
SDL_DateTime pathDt;
|
||||
fileInfoToAdd.lastModifyTime = pathInfo.modify_time;
|
||||
if(SDL_TimeToDateTime(pathInfo.modify_time, &pathDt, true)) {
|
||||
fileInfoToAdd.lastModifyDate = sdl_time_to_nice_access_time(pathDt, main.conf.dateFormat, main.conf.timeFormat);
|
||||
}
|
||||
}
|
||||
|
||||
fL.emplace_back(fileInfoToAdd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fileListOptional.value();
|
||||
void FileSelectScreen::start_edit_mode() {
|
||||
for(auto& f : fileList)
|
||||
f.selected = false;
|
||||
editMode = true;
|
||||
}
|
||||
|
||||
void FileSelectScreen::input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) {
|
||||
|
|
@ -248,3 +550,10 @@ void FileSelectScreen::input_open_infinipaint_file_callback(const CustomEvents::
|
|||
void FileSelectScreen::draw(SkCanvas* canvas) {
|
||||
canvas->clear(main.g.gui.io.theme->backColor1);
|
||||
}
|
||||
|
||||
FileSelectScreen::~FileSelectScreen() {
|
||||
nlohmann::json j;
|
||||
nlohmann::to_json(j, trashInfo);
|
||||
std::string saveJson = nlohmann::to_string(j);
|
||||
SDL_SaveFile(trashInfoPath.string().c_str(), saveJson.c_str(), saveJson.size());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#pragma once
|
||||
#include "Screen.hpp"
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
|
||||
class FileSelectScreen : public Screen {
|
||||
public:
|
||||
|
|
@ -7,25 +9,76 @@ class FileSelectScreen : public Screen {
|
|||
virtual void gui_layout_run() override;
|
||||
virtual void draw(SkCanvas* canvas) override;
|
||||
virtual void input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) override;
|
||||
|
||||
struct TrashInfo {
|
||||
struct TrashFile {
|
||||
SDL_Time trashTime;
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(TrashFile, trashTime)
|
||||
};
|
||||
std::unordered_map<std::string, TrashFile> files;
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(TrashInfo, files)
|
||||
};
|
||||
~FileSelectScreen();
|
||||
|
||||
private:
|
||||
std::filesystem::path savePath;
|
||||
std::filesystem::path trashPath;
|
||||
std::filesystem::path trashInfoPath;
|
||||
|
||||
struct FileInfo {
|
||||
std::string fileName;
|
||||
SDL_Time lastModifyTime;
|
||||
std::string lastModifyDate;
|
||||
bool selected = false;
|
||||
};
|
||||
const std::vector<FileInfo>& get_file_list(const std::string& folder);
|
||||
std::optional<std::vector<FileInfo>> fileListOptional;
|
||||
|
||||
void update_file_list(std::vector<FileInfo>& fL, const std::filesystem::path& savePath, bool trashUpdate);
|
||||
|
||||
TrashInfo trashInfo;
|
||||
std::vector<FileInfo> fileList;
|
||||
|
||||
void main_display();
|
||||
void main_menu();
|
||||
void file_view();
|
||||
bool main_menu_fills_screen();
|
||||
void file_view();
|
||||
void file_view_edit();
|
||||
void menu_black_box();
|
||||
void title_bar(std::string_view title);
|
||||
void edit_action_bar();
|
||||
void edit_title_bar();
|
||||
void title_bar();
|
||||
void text_transparent_option_button(const char* id, const char* text, const std::function<void()>& onClick);
|
||||
void icon_text_transparent_option_selected_button(const char* id, const std::string& svgPath, const char* text, bool isSelected, const std::function<void()>& onClick);
|
||||
void edit_action_bar_button(const char* id, const std::string& svgPath, const char* text, const std::function<void()>& onClick);
|
||||
|
||||
enum class TrashMoveType {
|
||||
NONE,
|
||||
MOVE_TO_TRASH,
|
||||
MOVE_OUT_OF_TRASH
|
||||
};
|
||||
void move_selected_files(const std::filesystem::path& fromPath, const std::filesystem::path& toPath, TrashMoveType trashMoveType);
|
||||
void delete_selected_files_in_trash();
|
||||
|
||||
enum class FileViewType {
|
||||
LARGE_GRID,
|
||||
MEDIUM_GRID,
|
||||
SMALL_GRID
|
||||
} fileViewType = FileViewType::LARGE_GRID;
|
||||
|
||||
enum class MoreOptionsMenu {
|
||||
CLOSED,
|
||||
MAIN,
|
||||
VIEW
|
||||
} moreOptionsMenu = MoreOptionsMenu::CLOSED;
|
||||
|
||||
enum class SelectedMenu {
|
||||
FILES,
|
||||
TRASH,
|
||||
SETTINGS
|
||||
} selectedMenu = SelectedMenu::FILES;
|
||||
|
||||
void start_edit_mode();
|
||||
size_t numberOfSelectedEntries;
|
||||
bool editMode = false;
|
||||
|
||||
bool mainMenuOpen = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ class MainProgram;
|
|||
|
||||
class World {
|
||||
public:
|
||||
static constexpr std::string DOT_FILE_EXTENSION = ".infpnt";
|
||||
static constexpr std::string FILE_EXTENSION = "infpnt";
|
||||
static constexpr size_t CHAT_SIZE = 10;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "Helpers/SCollision.hpp"
|
||||
#include "Helpers/StringHelpers.hpp"
|
||||
#include "Helpers/FileDownloader.hpp"
|
||||
#include "Screens/FileSelectScreen.hpp"
|
||||
#include "VersionConstants.hpp"
|
||||
#include "include/gpu/GpuTypes.h"
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
|
|
@ -535,6 +536,8 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
mS.m->screen = std::make_unique<FileSelectScreen>(*mS.m);
|
||||
|
||||
mS.m->update(); // Run update once to make sure that callbacks dont crash
|
||||
|
||||
#ifdef NDEBUG
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue