diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index 60771fd..f26ca25 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -274,6 +274,11 @@ void DrawingProgram::update() { controls.previousMouseWorldPos = controls.currentMouseWorldPos; controls.currentMouseWorldPos = world.get_mouse_world_pos(); + if(addFileInNextFrame) { + add_file_to_canvas_by_path_execute(addFileInfo.first, addFileInfo.second); + addFileInNextFrame = false; + } + drag_drop_update(); if(world.main.input.key(InputManager::KEY_DRAW_TOOL_BRUSH).pressed) @@ -341,31 +346,65 @@ void DrawingProgram::update() { void DrawingProgram::drag_drop_update() { if(controls.cursorHoveringOverCanvas) { for(auto& droppedItem : world.main.input.droppedItems) { - if(droppedItem.isFile && std::filesystem::is_regular_file(droppedItem.droppedData)) { - ServerClientID imageID = world.rMan.add_resource_file(droppedItem.droppedData); - std::shared_ptr display = world.rMan.get_display_data(imageID); - Vector2f imTrueDim = display->get_dimensions(); - auto img(std::make_shared()); - img->coords = world.drawData.cam.c; - float imWidth = imTrueDim.x() / (imTrueDim.x() + imTrueDim.y()); - float imHeight = imTrueDim.y() / (imTrueDim.x() + imTrueDim.y()); - Vector2f imDim = Vector2f{world.main.window.size.x() * imWidth, world.main.window.size.x() * imHeight} * display->get_dimension_scale(); - Vector2f dropPos = world.main.input.mouse.pos; - // dropPos = droppedItem.pos; // Doesnt work properly with emscripten - img->d.p1 = dropPos - imDim; - img->d.p2 = dropPos + imDim; - img->d.imageID = imageID; - img->initialize_draw_data(*this); - img->finalize_update(colliderAllocated); - uint64_t placement = components.client_list().size(); - components.client_insert(placement, img); - img->client_send_place(*this, placement); - add_undo_place_component(placement, img); - } + if(droppedItem.isFile && std::filesystem::is_regular_file(droppedItem.droppedData)) + add_file_to_canvas_by_path(droppedItem.droppedData, world.main.input.mouse.pos, true); } } } +void DrawingProgram::add_file_to_canvas_by_path(const std::string& filePath, Vector2f dropPos, bool addInSameThread) { + if(addInSameThread) + add_file_to_canvas_by_path_execute(filePath, dropPos); + else if(!addFileInNextFrame) { + addFileInfo = {filePath, dropPos}; + addFileInNextFrame = true; + } +} + +void DrawingProgram::add_file_to_canvas_by_path_execute(const std::string& filePath, Vector2f dropPos) { + ServerClientID imageID = world.rMan.add_resource_file(filePath); + std::shared_ptr display = world.rMan.get_display_data(imageID); + Vector2f imTrueDim = display->get_dimensions(); + auto img(std::make_shared()); + img->coords = world.drawData.cam.c; + float imWidth = imTrueDim.x() / (imTrueDim.x() + imTrueDim.y()); + float imHeight = imTrueDim.y() / (imTrueDim.x() + imTrueDim.y()); + Vector2f imDim = Vector2f{world.main.window.size.x() * imWidth, world.main.window.size.x() * imHeight} * display->get_dimension_scale(); + img->d.p1 = dropPos - imDim; + img->d.p2 = dropPos + imDim; + img->d.imageID = imageID; + img->initialize_draw_data(*this); + img->finalize_update(colliderAllocated); + uint64_t placement = components.client_list().size(); + components.client_insert(placement, img); + img->client_send_place(*this, placement); + add_undo_place_component(placement, img); +} + +void DrawingProgram::add_file_to_canvas_by_data(const std::string& fileName, std::string_view fileBuffer, Vector2f dropPos) { + ResourceData newResource; + newResource.data = std::make_shared(fileBuffer); + newResource.name = fileName; + ServerClientID imageID = world.rMan.add_resource(newResource); + + std::shared_ptr display = world.rMan.get_display_data(imageID); + Vector2f imTrueDim = display->get_dimensions(); + auto img(std::make_shared()); + img->coords = world.drawData.cam.c; + float imWidth = imTrueDim.x() / (imTrueDim.x() + imTrueDim.y()); + float imHeight = imTrueDim.y() / (imTrueDim.x() + imTrueDim.y()); + Vector2f imDim = Vector2f{world.main.window.size.x() * imWidth, world.main.window.size.x() * imHeight} * display->get_dimension_scale(); + img->d.p1 = dropPos - imDim; + img->d.p2 = dropPos + imDim; + img->d.imageID = imageID; + img->initialize_draw_data(*this); + img->finalize_update(colliderAllocated); + uint64_t placement = components.client_list().size(); + components.client_insert(placement, img); + img->client_send_place(*this, placement); + add_undo_place_component(placement, img); +} + void DrawingProgram::reset_tools() { rectSelectTool.reset_tool(); textBoxTool.reset_tool(); diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index 1257c41..6c44374 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -41,12 +41,20 @@ class DrawingProgram { void free_collider_memory(); void allocate_collider_memory(); + void add_file_to_canvas_by_path(const std::string& filePath, Vector2f dropPos, bool addInSameThread); + void add_file_to_canvas_by_data(const std::string& fileName, std::string_view fileBuffer, Vector2f dropPos); + bool colliderAllocated = false; CollabList, ServerClientID> components; Vector4f* get_foreground_color_ptr(); private: + std::atomic addFileInNextFrame = false; + std::pair addFileInfo; + + void add_file_to_canvas_by_path_execute(const std::string& filePath, Vector2f dropPos); + void draw_cache(SkCanvas* canvas, const DrawData& drawData, const std::shared_ptr& lastComp); void check_all_collisions_base(const SCollision::ColliderCollection& checkAgainstWorld, const SCollision::ColliderCollection& checkAgainstCam); diff --git a/src/Toolbar.cpp b/src/Toolbar.cpp index 56b18f9..deb145a 100644 --- a/src/Toolbar.cpp +++ b/src/Toolbar.cpp @@ -451,6 +451,22 @@ void Toolbar::top_toolbar() { save_as_func(); if(gui.text_button_wide("open file", "Open")) open_world_file(World::CONNECTIONTYPE_LOCAL, "", ""); + if(gui.text_button_wide("add image or file to canvas", "Add Image/File to Canvas")) { + #ifdef __EMSCRIPTEN__ + emscripten_browser_file::upload("*", [](std::string const& fileName, std::string const& mimeType, std::string_view buffer, void* callbackData) { + if(!buffer.empty()) { + World* world = (World*)callbackData; + world->drawProg.add_file_to_canvas_by_data(fileName, buffer, world->main.window.size.cast() / 2.0f); + } + }, main.world.get()); + #else + 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); + }); + #endif + } if(main.world->network_being_used()) { if(gui.text_button_wide("lobby info", "Lobby Info")) { optionsMenuOpen = true;