From fe37c3348bef9c77a09a15815eff3113eebf5410 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Thu, 5 Mar 2026 15:03:05 +0300 Subject: [PATCH] Screenshot tool and saving/reading files works on android --- src/DrawingProgram/Tools/ScreenshotTool.cpp | 34 +++++++-------------- src/DrawingProgram/Tools/ScreenshotTool.hpp | 5 +-- src/GUIStuff/Elements/Element.hpp | 1 + src/ResourceManager.cpp | 33 +++++--------------- src/Toolbar.cpp | 6 ++-- src/World.cpp | 9 +++--- 6 files changed, 30 insertions(+), 58 deletions(-) diff --git a/src/DrawingProgram/Tools/ScreenshotTool.cpp b/src/DrawingProgram/Tools/ScreenshotTool.cpp index 9429d12..f45bbf1 100644 --- a/src/DrawingProgram/Tools/ScreenshotTool.cpp +++ b/src/DrawingProgram/Tools/ScreenshotTool.cpp @@ -103,7 +103,8 @@ void ScreenshotTool::gui_toolbox() { auto world = w.lock(); if(world && world->drawProg.drawTool->get_type() == DrawingProgramToolType::SCREENSHOT) { ScreenshotTool* screenshotTool = static_cast(world->drawProg.drawTool.get()); - screenshotTool->controls.screenshotSavePath = force_extension_on_path(p, setExtensionFilter.extensions); + screenshotTool->controls.screenshotSavePath = p; + screenshotTool->controls.screenshotSaveType = world->main.toolConfig.screenshot.selectedType; screenshotTool->controls.setToTakeScreenshot = true; } }, "screenshot", true); @@ -281,24 +282,13 @@ bool ScreenshotTool::dragging_area_update(const Vector2f& camCursorPos) { void ScreenshotTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) { } -void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) { +void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath, ScreenshotType screenshotType) { if(controls.imageSize.x() <= 0 || controls.imageSize.y() <= 0) { std::cout << "[ScreenshotTool::take_screenshot] Image size is 0 or negative" << std::endl; return; } - std::string ext = filePath.extension().string(); - size_t extType = SCREENSHOT_JPG; - if(ext == ".jpg" || ext == ".jpeg") - extType = SCREENSHOT_JPG; - else if(ext == ".png") - extType = SCREENSHOT_PNG; - else if(ext == ".webp") - extType = SCREENSHOT_WEBP; - else if(ext == ".svg") - extType = SCREENSHOT_SVG; - - if(extType != SCREENSHOT_SVG) { + if(screenshotType != SCREENSHOT_SVG) { size_t imageByteSize = (size_t)controls.imageSize.x() * (size_t)controls.imageSize.y() * 4; size_t imageRowSize = 4 * controls.imageSize.x(); @@ -315,12 +305,12 @@ void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) { for(int i = 0; i < controls.imageSize.x(); i += drawP.world.main.window.size.x()) for(int j = 0; j < controls.imageSize.y(); j += drawP.world.main.window.size.y()) - take_screenshot_area_hw(surface, screenshotCanvas, finalImgRawData.data(), controls.imageSize, Vector2i{i, j}, Vector2i{std::min(drawP.world.main.window.size.x(), controls.imageSize.x() - i), std::min(drawP.world.main.window.size.y(), controls.imageSize.y() - j)}, drawP.world.main.window.size, extType != 0 && controls.transparentBackground); + take_screenshot_area_hw(surface, screenshotCanvas, finalImgRawData.data(), controls.imageSize, Vector2i{i, j}, Vector2i{std::min(drawP.world.main.window.size.x(), controls.imageSize.x() - i), std::min(drawP.world.main.window.size.y(), controls.imageSize.y() - j)}, drawP.world.main.window.size, screenshotType != SCREENSHOT_JPG && controls.transparentBackground); bool success = false; SkDynamicMemoryWStream out; - switch(extType) { + switch(screenshotType) { case SCREENSHOT_JPG: success = SkJpegEncoder::Encode(&out, finalImgData, {}); break; @@ -341,10 +331,9 @@ void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) { #ifndef __EMSCRIPTEN__ try { - std::ofstream fi(filePath, std::ios::out | std::ios::binary); auto skData = out.detachAsData(); - fi.write((const char*)skData->bytes(), skData->size()); - fi.close(); + if(!SDL_SaveFile(filePath.c_str(), skData->bytes(), skData->size())) + throw std::runtime_error("SDL_SaveFile failed with error: " + std::string(SDL_GetError())); } catch(const std::exception& e) { Logger::get().log("WORLDFATAL", std::string("[ScreenshotTool::take_screenshot] Save screenshot error: ") + e.what()); @@ -372,10 +361,9 @@ void ScreenshotTool::take_screenshot(const std::filesystem::path& filePath) { #ifndef __EMSCRIPTEN__ try { - std::ofstream fi(filePath, std::ios::out | std::ios::binary); auto skData = out.detachAsData(); - fi.write((const char*)skData->bytes(), skData->size()); - fi.close(); + if(!SDL_SaveFile(filePath.c_str(), skData->bytes(), skData->size())) + throw std::runtime_error("SDL_SaveFile failed with error: " + std::string(SDL_GetError())); } catch(const std::exception& e) { Logger::get().log("WORLDFATAL", std::string("[ScreenshotTool::take_screenshot] Save screenshot error: ") + e.what()); @@ -467,7 +455,7 @@ void ScreenshotTool::switch_tool(DrawingProgramToolType newTool) { void ScreenshotTool::tool_update() { if(controls.setToTakeScreenshot) { controls.setToTakeScreenshot = false; - take_screenshot(controls.screenshotSavePath); + take_screenshot(controls.screenshotSavePath, controls.screenshotSaveType); } if(controls.selectionMode == ScreenshotControls::SelectionMode::SELECTION_EXISTS) selection_exists_update(); diff --git a/src/DrawingProgram/Tools/ScreenshotTool.hpp b/src/DrawingProgram/Tools/ScreenshotTool.hpp index b561ad7..2aec17d 100644 --- a/src/DrawingProgram/Tools/ScreenshotTool.hpp +++ b/src/DrawingProgram/Tools/ScreenshotTool.hpp @@ -29,7 +29,7 @@ class ScreenshotTool : public DrawingProgramToolBase { }; private: void commit_rect(); - void take_screenshot(const std::filesystem::path& filePath); + void take_screenshot(const std::filesystem::path& filePath, ScreenshotType screenshotType); void take_screenshot_area_hw(const sk_sp& surface, SkCanvas* canvas, void* fullImgRawData, const Vector2i& fullImageSize, const Vector2i& sectionImagePos, const Vector2i& sectionImageSize, const Vector2i& canvasSize, bool transparentBackground); void take_screenshot_svg(SkCanvas* canvas, bool transparentBackground); @@ -47,7 +47,7 @@ class ScreenshotTool : public DrawingProgramToolBase { DRAGGING_BORDER, SELECTION_EXISTS, DRAGGING_AREA - } selectionMode; + } selectionMode = SelectionMode::NO_SELECTION; int dragType = 0; Vector2i imageSize = {0, 0}; std::array, 8> circles; @@ -59,6 +59,7 @@ class ScreenshotTool : public DrawingProgramToolBase { std::atomic setToTakeScreenshot = false; std::filesystem::path screenshotSavePath; + ScreenshotType screenshotSaveType; } controls; bool dragging_border_update(const Vector2f& camCursorPos); bool selection_exists_update(); diff --git a/src/GUIStuff/Elements/Element.hpp b/src/GUIStuff/Elements/Element.hpp index 77ac80e..0de37e3 100644 --- a/src/GUIStuff/Elements/Element.hpp +++ b/src/GUIStuff/Elements/Element.hpp @@ -108,6 +108,7 @@ struct UpdateInputData { std::vector> hoverObstructingCircles; bool acceptingTextInput = false; float deltaTime = 0.0f; + bool isTouch = true; std::shared_ptr fonts; sk_sp textTypeface; diff --git a/src/ResourceManager.cpp b/src/ResourceManager.cpp index bc5e66e..d0c214d 100644 --- a/src/ResourceManager.cpp +++ b/src/ResourceManager.cpp @@ -85,36 +85,17 @@ void ResourceManager::update() { } NetworkingObjects::NetObjTemporaryPtr ResourceManager::add_resource_file(const std::filesystem::path& filePath) { - // https://nullptr.org/cpp-read-file-into-string/ - std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate); - if(!file.is_open()) { - Logger::get().log("INFO", "[ResourceManager::add_resource_file] Could not open file " + filePath.string()); - return {}; - } - - size_t resourcesize; - - auto tellgResult = file.tellg(); - - if(tellgResult == -1) { - Logger::get().log("INFO", "[ResourceManager::add_resource_file] tellg failed for file " + filePath.string()); - return {}; - } - - resourcesize = static_cast(tellgResult); - - file.seekg(0, std::ios_base::beg); - ResourceData resource; resource.data = std::make_shared(); resource.name = std::filesystem::path(filePath).filename().string(); - std::string& toPlaceIn = *resource.data; - toPlaceIn.resize(resourcesize); - - file.read(toPlaceIn.data(), resourcesize); - - file.close(); + try { + *resource.data = read_file_to_string(filePath); + } + catch(...) { + Logger::get().log("INFO", "[ResourceManager::add_resource_file] Could not open file " + filePath.string()); + return {}; + } Logger::get().log("INFO", "[ResourceManager::add_resource_file] Successfully read file " + filePath.string()); diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 0ff3f43..e9efb3d 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -1,6 +1,7 @@ #include "Toolbar.hpp" #include "DrawingProgram/Tools/DrawingProgramToolBase.hpp" #include "DrawingProgram/Tools/ScreenshotTool.hpp" +#include "FileHelpers.hpp" #include "Helpers/ConvertVec.hpp" #include "Helpers/FileDownloader.hpp" #include "Helpers/MathExtras.hpp" @@ -746,7 +747,7 @@ void Toolbar::top_toolbar() { open_file_selector("Open File", {{"Any File", "*"}}, [w = make_weak_ptr(main.world)](const std::filesystem::path& p, const auto& e) { auto wLock = w.lock(); if(wLock) - wLock->drawProg.add_file_to_canvas_by_path(p.string(), wLock->main.window.size.cast() / 2.0f, false); + wLock->drawProg.add_file_to_canvas_by_path(p, wLock->main.window.size.cast() / 2.0f, false); else Logger::get().log("INFO", "Loading image to canvas that has been destroyed"); }); @@ -2252,7 +2253,7 @@ void Toolbar::file_picker_gui() { if(gui.text_button_wide("filepicker done", "Done") || isDoneByDoubleClick) { if(!filePicker.fileName.empty()) { pathToRet = filePicker.currentSearchPath / filePicker.fileName; - filePicker.postSelectionFunc(pathToRet, filePicker.extensionFiltersComplete[filePicker.extensionSelected]); + filePicker.postSelectionFunc(force_extension_on_path(pathToRet, filePicker.extensionFiltersComplete[filePicker.extensionSelected].extensions), filePicker.extensionFiltersComplete[filePicker.extensionSelected]); } filePicker.isOpen = false; } @@ -2403,6 +2404,7 @@ void Toolbar::start_gui() { io->hoverObstructed = false; io->hoverObstructingAABBs.clear(); io->hoverObstructingCircles.clear(); + io->isTouch = main.input.isTouchDevice; gui.begin(); } diff --git a/src/World.cpp b/src/World.cpp index c79bfef..1f6768c 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -440,7 +440,7 @@ void World::autosave_to_directory(const std::filesystem::path& directoryToSaveAt void World::save_to_file(const std::filesystem::path& filePathToSaveAt) { try { - filePath = force_extension_on_path(filePathToSaveAt, FILE_EXTENSION); + filePath = filePathToSaveAt; std::stringstream f; f.write(VersionConstants::CURRENT_SAVEFILE_HEADER.c_str(), VersionConstants::SAVEFILE_HEADER_LEN); @@ -468,9 +468,8 @@ void World::save_to_file(const std::filesystem::path& filePathToSaveAt) { f.view() ); #else - std::ofstream fi(filePath, std::ios::out | std::ios::binary); - fi << f.view(); - fi.close(); + if(!SDL_SaveFile(filePath.c_str(), f.view().data(), f.view().size())) + throw std::runtime_error("SDL_SaveFile failed with error: " + std::string(SDL_GetError())); #endif Logger::get().log("USERINFO", "File saved"); @@ -489,7 +488,7 @@ void World::load_empty_canvas() { } void World::load_from_file(const std::filesystem::path& filePathToLoadFrom, std::string_view buffer) { - filePath = force_extension_on_path(filePathToLoadFrom, FILE_EXTENSION); + filePath = filePathToLoadFrom; std::string byteDataFromFile;