/* * InfiniPaint * Copyright (C) 2025-2026 Yousef Khadadeh * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "DrawingProgramLayerFolder.hpp" #include "DrawingProgramLayerListItem.hpp" #include "DrawingProgramLayer.hpp" #include #include "DrawingProgramLayerManager.hpp" #include "../DrawingProgram.hpp" #include "../../World.hpp" void DrawingProgramLayerFolder::draw(SkCanvas* canvas, const DrawData& drawData) const { for(auto& p : (*folderList) | std::views::reverse) p.obj->draw(canvas, drawData); } void DrawingProgramLayerFolder::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) { folderList->set_insert_callback([&](auto& c) { layerMan.drawP.drawCache.clear_own_cached_surfaces(); c->obj->set_component_list_callbacks(layerMan); layerMan.drawP.world.set_to_layout_gui_if_focus(); }); folderList->set_erase_callback([&](auto& c) { layerMan.drawP.drawCache.clear_own_cached_surfaces(); c->obj->set_to_erase(); layerMan.drawP.world.set_to_layout_gui_if_focus(); }); folderList->set_move_callback([&](auto& c, uint32_t oldPos) { layerMan.drawP.drawCache.clear_own_cached_surfaces(); layerMan.drawP.world.set_to_layout_gui_if_focus(); }); for(auto& listItem : *folderList) listItem.obj->set_component_list_callbacks(layerMan); } void DrawingProgramLayerFolder::set_to_erase() { for(auto& listItem : *folderList) listItem.obj->set_to_erase(); } void DrawingProgramLayerFolder::get_flattened_component_list(std::vector& objList) const { for(auto& listItem : (*folderList) | std::views::reverse) listItem.obj->get_flattened_component_list(objList); } NetworkingObjects::NetObjWeakPtr DrawingProgramLayerFolder::get_initial_editing_layer() const { // BFS, select a layer that's closest to root as possible for(auto& c : *folderList) { if(!c.obj->is_folder()) return c.obj; } for(auto& c : *folderList) { if(c.obj->is_folder()) { NetworkingObjects::NetObjWeakPtr toRet = c.obj->get_folder().get_initial_editing_layer(); if(!toRet.expired()) return toRet; } } return {}; } void DrawingProgramLayerFolder::scale_up(const WorldScalar& scaleUpAmount) { for(auto& p : *folderList) p.obj->scale_up(scaleUpAmount); } void DrawingProgramLayerFolder::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version, DrawingProgramLayerManager& layerMan) { folderList = layerMan.drawP.world.netObjMan.make_obj>(); uint32_t folderListSize; a(folderListSize); for(uint32_t i = 0; i < folderListSize; i++) { DrawingProgramLayerListItem* item = new DrawingProgramLayerListItem(); item->load_file(a, version, layerMan); folderList->push_back_and_send_create(folderList, item); } } void DrawingProgramLayerFolder::save_file(cereal::PortableBinaryOutputArchive& a) const { a(folderList->size()); for(auto& listItem : *folderList) listItem.obj->save_file(a); } void DrawingProgramLayerFolder::erase_invalid_components() { for(auto& listItem : *folderList) listItem.obj->erase_invalid_components(); } void DrawingProgramLayerFolder::get_used_resources(std::unordered_set& resourceSet) const { for(auto& listItem : *folderList) listItem.obj->get_used_resources(resourceSet); }