Added a button to upload images and files to the canvas

This commit is contained in:
Yousef Khadadeh 2025-07-10 22:09:56 +03:00
parent c49f7c8531
commit 6370dfbb85
3 changed files with 84 additions and 21 deletions

View file

@ -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<ResourceDisplay> display = world.rMan.get_display_data(imageID);
Vector2f imTrueDim = display->get_dimensions();
auto img(std::make_shared<DrawImage>());
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<ResourceDisplay> display = world.rMan.get_display_data(imageID);
Vector2f imTrueDim = display->get_dimensions();
auto img(std::make_shared<DrawImage>());
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<std::string>(fileBuffer);
newResource.name = fileName;
ServerClientID imageID = world.rMan.add_resource(newResource);
std::shared_ptr<ResourceDisplay> display = world.rMan.get_display_data(imageID);
Vector2f imTrueDim = display->get_dimensions();
auto img(std::make_shared<DrawImage>());
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();

View file

@ -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<std::shared_ptr<DrawComponent>, ServerClientID> components;
Vector4f* get_foreground_color_ptr();
private:
std::atomic<bool> addFileInNextFrame = false;
std::pair<std::string, Vector2f> 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<DrawComponent>& lastComp);
void check_all_collisions_base(const SCollision::ColliderCollection<WorldScalar>& checkAgainstWorld, const SCollision::ColliderCollection<float>& checkAgainstCam);

View file

@ -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<float>() / 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<float>() / 2.0f, false);
});
#endif
}
if(main.world->network_being_used()) {
if(gui.text_button_wide("lobby info", "Lobby Info")) {
optionsMenuOpen = true;