2026-05-11 23:06:39 +03:00
|
|
|
/*
|
|
|
|
|
* 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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2025-12-24 12:42:27 +03:00
|
|
|
#include "DrawingProgramLayerListItem.hpp"
|
|
|
|
|
#include "DrawingProgramLayerFolder.hpp"
|
|
|
|
|
#include <cereal/types/string.hpp>
|
|
|
|
|
#include "DrawingProgramLayer.hpp"
|
|
|
|
|
#include "../../World.hpp"
|
2026-10-25 18:07:47 +01:00
|
|
|
#include "../../MainProgram.hpp"
|
2025-12-25 19:37:41 +03:00
|
|
|
#include "SerializedBlendMode.hpp"
|
2025-12-24 12:42:27 +03:00
|
|
|
|
|
|
|
|
using namespace NetworkingObjects;
|
|
|
|
|
|
2026-01-04 11:37:38 +03:00
|
|
|
void DrawingProgramLayerListItemUndoData::scale_up(const WorldScalar& scaleUpAmount) {
|
|
|
|
|
if(folderData) {
|
|
|
|
|
for(auto& l : folderData.value())
|
|
|
|
|
l.scale_up(scaleUpAmount);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
for(auto& c : layerData.value())
|
|
|
|
|
c.copyData->scale_up(scaleUpAmount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 12:42:27 +03:00
|
|
|
DrawingProgramLayerListItem::DrawingProgramLayerListItem() {}
|
|
|
|
|
|
|
|
|
|
DrawingProgramLayerListItem::DrawingProgramLayerListItem(NetworkingObjects::NetObjManager& netObjMan, const std::string& initName, bool isFolder) {
|
|
|
|
|
if(isFolder) {
|
|
|
|
|
folderData = std::make_unique<DrawingProgramLayerFolder>();
|
|
|
|
|
folderData->folderList = netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<DrawingProgramLayerListItem>>();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
layerData = std::make_unique<DrawingProgramLayer>();
|
|
|
|
|
layerData->components = netObjMan.make_obj<CanvasComponentContainer::NetList>();
|
|
|
|
|
}
|
|
|
|
|
nameData = netObjMan.make_obj<NameData>();
|
|
|
|
|
nameData->name = initName;
|
|
|
|
|
displayData = netObjMan.make_obj<DisplayData>();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-03 19:05:00 +03:00
|
|
|
DrawingProgramLayerListItem::DrawingProgramLayerListItem(World& w, const DrawingProgramLayerListItemUndoData& initData) {
|
|
|
|
|
if(initData.folderData) {
|
|
|
|
|
auto& initFolderList = initData.folderData.value();
|
|
|
|
|
folderData = std::make_unique<DrawingProgramLayerFolder>();
|
|
|
|
|
folderData->folderList = w.netObjMan.make_obj<NetworkingObjects::NetObjOrderedList<DrawingProgramLayerListItem>>();
|
2026-01-04 16:50:47 +03:00
|
|
|
w.undo.register_new_netid_to_existing_undoid(initData.containerUndoID, folderData->folderList.get_net_id());
|
2026-01-03 19:05:00 +03:00
|
|
|
for(auto& initFolder : initFolderList) {
|
|
|
|
|
auto it = folderData->folderList->emplace_back_direct(folderData->folderList, w, initFolder);
|
|
|
|
|
w.undo.register_new_netid_to_existing_undoid(initFolder.undoID, it->obj.get_net_id());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
auto& initComponentList = initData.layerData.value();
|
|
|
|
|
layerData = std::make_unique<DrawingProgramLayer>();
|
|
|
|
|
layerData->components = w.netObjMan.make_obj<CanvasComponentContainer::NetList>();
|
2026-01-04 16:50:47 +03:00
|
|
|
w.undo.register_new_netid_to_existing_undoid(initData.containerUndoID, layerData->components.get_net_id());
|
2026-01-03 19:05:00 +03:00
|
|
|
for(auto& initComponent : initComponentList) {
|
|
|
|
|
auto it = layerData->components->emplace_back_direct(layerData->components, w.netObjMan, *initComponent.copyData);
|
|
|
|
|
w.undo.register_new_netid_to_existing_undoid(initComponent.undoID, it->obj.get_net_id());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
nameData = w.netObjMan.make_obj<NameData>();
|
|
|
|
|
nameData->name = initData.metaInfo.name;
|
|
|
|
|
displayData = w.netObjMan.make_obj<DisplayData>();
|
|
|
|
|
displayData->alpha = initData.metaInfo.alpha;
|
|
|
|
|
displayData->blendMode = initData.metaInfo.blendMode;
|
2026-10-25 18:07:47 +01:00
|
|
|
displayData->playerLocked = initData.metaInfo.playerLocked;
|
|
|
|
|
displayData->fogLayer = initData.metaInfo.fogLayer;
|
2026-01-03 19:05:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawingProgramLayerListItemUndoData DrawingProgramLayerListItem::get_undo_data(WorldUndoManager& u) const {
|
|
|
|
|
DrawingProgramLayerListItemUndoData toRet;
|
|
|
|
|
toRet.metaInfo.name = nameData->name;
|
|
|
|
|
toRet.metaInfo.blendMode = displayData->blendMode;
|
|
|
|
|
toRet.metaInfo.alpha = displayData->alpha;
|
2026-10-25 18:07:47 +01:00
|
|
|
toRet.metaInfo.playerLocked = displayData->playerLocked;
|
|
|
|
|
toRet.metaInfo.fogLayer = displayData->fogLayer;
|
2026-01-03 19:05:00 +03:00
|
|
|
if(folderData) {
|
2026-01-04 16:50:47 +03:00
|
|
|
toRet.containerUndoID = u.get_undoid_from_netid(folderData->folderList.get_net_id());
|
2026-01-03 19:05:00 +03:00
|
|
|
toRet.folderData = std::vector<DrawingProgramLayerListItemUndoData>();
|
|
|
|
|
auto& folderListToRet = toRet.folderData.value();
|
|
|
|
|
for(auto& f : *folderData->folderList) {
|
|
|
|
|
folderListToRet.emplace_back(f.obj->get_undo_data(u));
|
|
|
|
|
folderListToRet.back().undoID = u.get_undoid_from_netid(f.obj.get_net_id());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2026-01-04 16:50:47 +03:00
|
|
|
toRet.containerUndoID = u.get_undoid_from_netid(layerData->components.get_net_id());
|
2026-01-03 19:05:00 +03:00
|
|
|
toRet.layerData = std::vector<DrawingProgramComponentUndoData>();
|
|
|
|
|
auto& layerListToRet = toRet.layerData.value();
|
|
|
|
|
for(auto& c : *layerData->components)
|
|
|
|
|
layerListToRet.emplace_back(u.get_undoid_from_netid(c.obj.get_net_id()), c.obj->get_data_copy());
|
|
|
|
|
}
|
|
|
|
|
return toRet;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 12:42:27 +03:00
|
|
|
void DrawingProgramLayerListItem::reassign_netobj_ids_call() {
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->folderList.reassign_ids();
|
|
|
|
|
else
|
|
|
|
|
layerData->components.reassign_ids();
|
|
|
|
|
nameData.reassign_ids();
|
|
|
|
|
displayData.reassign_ids();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-30 21:18:59 +03:00
|
|
|
void DrawingProgramLayerListItem::set_to_erase() {
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->set_to_erase();
|
|
|
|
|
else
|
|
|
|
|
layerData->set_to_erase();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-26 10:10:19 +03:00
|
|
|
void DrawingProgramLayerListItem::set_component_list_callbacks(DrawingProgramLayerManager &layerMan) {
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->set_component_list_callbacks(layerMan);
|
|
|
|
|
else
|
2025-12-28 17:34:33 +03:00
|
|
|
layerData->set_component_list_callbacks(*this, layerMan);
|
2025-12-26 10:10:19 +03:00
|
|
|
}
|
|
|
|
|
|
2025-12-30 19:46:08 +03:00
|
|
|
void DrawingProgramLayerListItem::get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfo*>& objList) const {
|
2025-12-26 19:52:36 +03:00
|
|
|
if(folderData)
|
|
|
|
|
folderData->get_flattened_component_list(objList);
|
|
|
|
|
else
|
|
|
|
|
layerData->get_flattened_component_list(objList);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-29 19:57:36 +03:00
|
|
|
void DrawingProgramLayerListItem::get_flattened_layer_list(std::vector<DrawingProgramLayerListItem*>& objList) {
|
|
|
|
|
if(folderData) {
|
2025-12-30 19:46:08 +03:00
|
|
|
for(auto& c : *folderData->folderList)
|
|
|
|
|
c.obj->get_flattened_layer_list(objList);
|
2025-12-29 19:57:36 +03:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
objList.emplace_back(this);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-29 20:11:24 +03:00
|
|
|
uint32_t DrawingProgramLayerListItem::get_component_count() const {
|
|
|
|
|
if(folderData) {
|
|
|
|
|
uint32_t toRet = 0;
|
2025-12-30 19:46:08 +03:00
|
|
|
for(auto& c : *folderData->folderList)
|
|
|
|
|
toRet += c.obj->get_component_count();
|
2025-12-29 20:11:24 +03:00
|
|
|
return toRet;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return layerData->components->size();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-31 16:30:56 +03:00
|
|
|
void DrawingProgramLayerListItem::scale_up(const WorldScalar& scaleUpAmount) {
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->scale_up(scaleUpAmount);
|
|
|
|
|
else
|
|
|
|
|
layerData->scale_up(scaleUpAmount);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 12:42:27 +03:00
|
|
|
bool DrawingProgramLayerListItem::is_folder() const {
|
|
|
|
|
return folderData != nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawingProgramLayerFolder& DrawingProgramLayerListItem::get_folder() const {
|
|
|
|
|
return *folderData;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawingProgramLayer& DrawingProgramLayerListItem::get_layer() const {
|
|
|
|
|
return *layerData;
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 22:46:02 +03:00
|
|
|
void DrawingProgramLayerListItem::load_file(cereal::PortableBinaryInputArchive& a, VersionNumber version, DrawingProgramLayerManager& layerMan) {
|
|
|
|
|
nameData = layerMan.drawP.world.netObjMan.make_obj<NameData>();
|
|
|
|
|
a(*nameData);
|
|
|
|
|
|
|
|
|
|
displayData = layerMan.drawP.world.netObjMan.make_obj<DisplayData>();
|
2026-10-25 18:07:47 +01:00
|
|
|
if(version >= VersionNumber(0, 8, 0)) {
|
|
|
|
|
a(*displayData);
|
|
|
|
|
// Normalize cereal bools (non-0/1 bytes must not stick as "true" forever).
|
|
|
|
|
displayData->visible = displayData->visible ? true : false;
|
|
|
|
|
displayData->playerLocked = displayData->playerLocked ? true : false;
|
|
|
|
|
displayData->fogLayer = displayData->fogLayer ? true : false;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
a(displayData->alpha, displayData->visible, displayData->blendMode);
|
|
|
|
|
displayData->visible = displayData->visible ? true : false;
|
|
|
|
|
displayData->playerLocked = false;
|
|
|
|
|
displayData->fogLayer = false;
|
|
|
|
|
}
|
2026-01-01 22:46:02 +03:00
|
|
|
|
|
|
|
|
bool isFolder;
|
|
|
|
|
a(isFolder);
|
|
|
|
|
if(isFolder) {
|
2026-10-25 18:07:47 +01:00
|
|
|
displayData->fogLayer = false;
|
2026-01-01 22:46:02 +03:00
|
|
|
folderData = std::make_unique<DrawingProgramLayerFolder>();
|
|
|
|
|
folderData->load_file(a, version, layerMan);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
layerData = std::make_unique<DrawingProgramLayer>();
|
|
|
|
|
layerData->load_file(a, version, layerMan);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawingProgramLayerListItem::save_file(cereal::PortableBinaryOutputArchive& a) const {
|
|
|
|
|
a(*nameData);
|
|
|
|
|
a(*displayData);
|
|
|
|
|
a(static_cast<bool>(folderData));
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->save_file(a);
|
|
|
|
|
else
|
|
|
|
|
layerData->save_file(a);
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-01 23:28:26 +03:00
|
|
|
void DrawingProgramLayerListItem::get_used_resources(std::unordered_set<NetworkingObjects::NetObjID>& resourceSet) const {
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->get_used_resources(resourceSet);
|
|
|
|
|
else
|
|
|
|
|
layerData->get_used_resources(resourceSet);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 17:18:28 +03:00
|
|
|
void DrawingProgramLayerListItem::draw(SkCanvas* canvas, const DrawData& drawData) const {
|
|
|
|
|
if(displayData->visible) {
|
2026-01-10 22:47:21 +03:00
|
|
|
if(!drawData.isSVGRender) {
|
|
|
|
|
SkPaint layerPaint;
|
|
|
|
|
layerPaint.setAlphaf(displayData->alpha);
|
|
|
|
|
layerPaint.setBlendMode(serialized_blend_mode_to_sk_blend_mode(displayData->blendMode));
|
|
|
|
|
canvas->saveLayer(nullptr, &layerPaint);
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-25 17:18:28 +03:00
|
|
|
if(folderData)
|
|
|
|
|
folderData->draw(canvas, drawData);
|
|
|
|
|
else
|
|
|
|
|
layerData->draw(canvas, drawData);
|
2026-01-10 22:47:21 +03:00
|
|
|
|
|
|
|
|
if(!drawData.isSVGRender)
|
|
|
|
|
canvas->restore();
|
2025-12-25 17:18:28 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 12:42:27 +03:00
|
|
|
void DrawingProgramLayerListItem::set_name(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, const std::string& newName) const {
|
|
|
|
|
if(nameData && nameData->name != newName) {
|
|
|
|
|
nameData->name = newName;
|
|
|
|
|
delayedNetObjMan.send_update_to_all<NameData>(nameData, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const std::string& DrawingProgramLayerListItem::get_name() const {
|
|
|
|
|
return nameData->name;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-28 17:34:33 +03:00
|
|
|
void DrawingProgramLayerListItem::set_alpha(DrawingProgramLayerManager& layerMan, float newAlpha) const {
|
2025-12-24 12:42:27 +03:00
|
|
|
if(displayData && displayData->alpha != newAlpha) {
|
|
|
|
|
displayData->alpha = newAlpha;
|
2025-12-29 15:04:32 +03:00
|
|
|
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
2025-12-28 17:34:33 +03:00
|
|
|
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
|
2025-12-24 12:42:27 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
float DrawingProgramLayerListItem::get_alpha() const {
|
|
|
|
|
return displayData->alpha;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-28 17:34:33 +03:00
|
|
|
void DrawingProgramLayerListItem::set_visible(DrawingProgramLayerManager& layerMan, bool newVisible) const {
|
2025-12-24 12:42:27 +03:00
|
|
|
if(displayData && displayData->visible != newVisible) {
|
|
|
|
|
displayData->visible = newVisible;
|
2025-12-29 15:04:32 +03:00
|
|
|
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
2025-12-28 17:34:33 +03:00
|
|
|
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
|
2025-12-24 12:42:27 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DrawingProgramLayerListItem::get_visible() const {
|
|
|
|
|
return displayData->visible;
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-28 17:34:33 +03:00
|
|
|
void DrawingProgramLayerListItem::set_blend_mode(DrawingProgramLayerManager& layerMan, SerializedBlendMode newBlendMode) const {
|
2025-12-25 19:37:41 +03:00
|
|
|
if(displayData && displayData->blendMode != newBlendMode) {
|
|
|
|
|
displayData->blendMode = newBlendMode;
|
2025-12-29 15:04:32 +03:00
|
|
|
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
2025-12-28 17:34:33 +03:00
|
|
|
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
|
2025-12-25 19:37:41 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SerializedBlendMode DrawingProgramLayerListItem::get_blend_mode() const {
|
|
|
|
|
return displayData->blendMode;
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-25 18:07:47 +01:00
|
|
|
void DrawingProgramLayerListItem::set_player_locked(DrawingProgramLayerManager& layerMan, bool locked) const {
|
|
|
|
|
if(!displayData)
|
|
|
|
|
return;
|
|
|
|
|
bool newLocked = locked || displayData->fogLayer;
|
|
|
|
|
if(displayData->playerLocked != newLocked) {
|
|
|
|
|
displayData->playerLocked = newLocked;
|
|
|
|
|
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
|
|
|
|
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
|
|
|
|
|
layerMan.refresh_fog_client_projection();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DrawingProgramLayerListItem::get_player_locked() const {
|
|
|
|
|
return displayData && displayData->playerLocked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawingProgramLayerListItem::set_fog_layer(DrawingProgramLayerManager& layerMan, bool fog) const {
|
|
|
|
|
if(!displayData || displayData->fogLayer == fog || is_folder())
|
|
|
|
|
return;
|
|
|
|
|
displayData->fogLayer = fog;
|
|
|
|
|
if(fog)
|
|
|
|
|
displayData->playerLocked = true;
|
|
|
|
|
layerMan.drawP.drawCache.clear_own_cached_surfaces();
|
|
|
|
|
layerMan.drawP.world.delayedUpdateObjectManager.send_update_to_all<DisplayData>(displayData, false);
|
|
|
|
|
layerMan.refresh_fog_client_projection();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DrawingProgramLayerListItem::is_fog_layer() const {
|
|
|
|
|
return displayData && displayData->fogLayer;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DrawingProgramLayerListItem::is_player_edit_blocked() const {
|
|
|
|
|
return is_fog_layer() || get_player_locked();
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-04 11:37:38 +03:00
|
|
|
void DrawingProgramLayerListItem::set_metainfo(DrawingProgramLayerManager& layerMan, const DrawingProgramLayerListItemMetaInfo& metaInfo) {
|
|
|
|
|
set_blend_mode(layerMan, metaInfo.blendMode);
|
|
|
|
|
set_alpha(layerMan, metaInfo.alpha);
|
|
|
|
|
set_name(layerMan.drawP.world.delayedUpdateObjectManager, metaInfo.name);
|
2026-10-25 18:07:47 +01:00
|
|
|
set_fog_layer(layerMan, metaInfo.fogLayer);
|
|
|
|
|
set_player_locked(layerMan, metaInfo.playerLocked || metaInfo.fogLayer);
|
2026-01-04 11:37:38 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DrawingProgramLayerListItemMetaInfo DrawingProgramLayerListItem::get_metainfo() const {
|
|
|
|
|
return DrawingProgramLayerListItemMetaInfo{
|
|
|
|
|
.name = get_name(),
|
|
|
|
|
.alpha = get_alpha(),
|
2026-10-25 18:07:47 +01:00
|
|
|
.blendMode = get_blend_mode(),
|
|
|
|
|
.playerLocked = get_player_locked(),
|
|
|
|
|
.fogLayer = is_fog_layer()
|
2026-01-04 11:37:38 +03:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-25 18:07:47 +01:00
|
|
|
void DrawingProgramLayerListItem::write_stripped_constructor(cereal::PortableBinaryOutputArchive& a, const std::unordered_set<NetworkingObjects::NetObjID>& hiddenComponentIds) const {
|
|
|
|
|
a(static_cast<bool>(folderData));
|
|
|
|
|
if(folderData) {
|
|
|
|
|
a(folderData->folderList.get_net_id());
|
|
|
|
|
a(static_cast<uint32_t>(folderData->folderList->size()));
|
|
|
|
|
for(auto& child : *folderData->folderList) {
|
|
|
|
|
a(child.obj.get_net_id());
|
|
|
|
|
child.obj->write_stripped_constructor(a, hiddenComponentIds);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
std::vector<NetworkingObjects::NetObjTemporaryPtr<CanvasComponentContainer>> keep;
|
|
|
|
|
for(auto& c : *layerData->components) {
|
|
|
|
|
if(!hiddenComponentIds.contains(c.obj.get_net_id()))
|
|
|
|
|
keep.emplace_back(c.obj);
|
|
|
|
|
}
|
|
|
|
|
a(layerData->components.get_net_id());
|
|
|
|
|
a(static_cast<uint32_t>(keep.size()));
|
|
|
|
|
for(auto& c : keep)
|
|
|
|
|
c.write_create_message(a);
|
|
|
|
|
}
|
|
|
|
|
nameData.write_create_message(a);
|
|
|
|
|
displayData.write_create_message(a);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-03 14:18:04 +03:00
|
|
|
void DrawingProgramLayerListItem::erase_invalid_components() {
|
|
|
|
|
if(folderData)
|
|
|
|
|
folderData->erase_invalid_components();
|
|
|
|
|
else
|
|
|
|
|
layerData->erase_invalid_components();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 12:42:27 +03:00
|
|
|
void DrawingProgramLayerListItem::register_class(World& w) {
|
|
|
|
|
w.netObjMan.register_class<DrawingProgramLayerListItem, DrawingProgramLayerListItem, DrawingProgramLayerListItem, DrawingProgramLayerListItem>({
|
|
|
|
|
.writeConstructorFuncClient = write_constructor_func,
|
|
|
|
|
.readConstructorFuncClient = read_constructor_func,
|
|
|
|
|
.readUpdateFuncClient = nullptr,
|
|
|
|
|
.writeConstructorFuncServer = write_constructor_func,
|
|
|
|
|
.readConstructorFuncServer = read_constructor_func,
|
|
|
|
|
.readUpdateFuncServer = nullptr,
|
|
|
|
|
});
|
2026-04-09 12:00:36 +03:00
|
|
|
w.delayedUpdateObjectManager.register_class<NameData>(w.netObjMan, NetworkingObjects::DelayUpdateSerializedClassManager::CustomConstructors<NameData>{
|
|
|
|
|
.postUpdateFunc = [&](NameData& o) {
|
|
|
|
|
w.set_to_layout_gui_if_focus();
|
|
|
|
|
}
|
|
|
|
|
});
|
2025-12-28 17:34:33 +03:00
|
|
|
w.delayedUpdateObjectManager.register_class<DisplayData>(w.netObjMan, NetworkingObjects::DelayUpdateSerializedClassManager::CustomConstructors<DisplayData>{
|
|
|
|
|
.postUpdateFunc = [&](DisplayData& o) {
|
2026-10-25 18:07:47 +01:00
|
|
|
(void)o;
|
2025-12-29 15:04:32 +03:00
|
|
|
w.drawProg.drawCache.clear_own_cached_surfaces();
|
2026-10-25 18:07:47 +01:00
|
|
|
w.drawProg.layerMan.ensure_editing_layer_is_editable();
|
2026-04-09 12:00:36 +03:00
|
|
|
w.set_to_layout_gui_if_focus();
|
2025-12-28 17:34:33 +03:00
|
|
|
}
|
|
|
|
|
});
|
2025-12-24 12:42:27 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawingProgramLayerListItem::write_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<DrawingProgramLayerListItem>& o, cereal::PortableBinaryOutputArchive& a) {
|
|
|
|
|
a(o->is_folder());
|
|
|
|
|
if(o->is_folder())
|
|
|
|
|
o->folderData->folderList.write_create_message(a);
|
|
|
|
|
else
|
|
|
|
|
o->layerData->components.write_create_message(a);
|
|
|
|
|
o->nameData.write_create_message(a);
|
|
|
|
|
o->displayData.write_create_message(a);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DrawingProgramLayerListItem::read_constructor_func(const NetworkingObjects::NetObjTemporaryPtr<DrawingProgramLayerListItem>& o, cereal::PortableBinaryInputArchive& a, const std::shared_ptr<NetServer::ClientData>& c) {
|
|
|
|
|
bool isFolder;
|
|
|
|
|
a(isFolder);
|
|
|
|
|
if(isFolder) {
|
|
|
|
|
o->folderData = std::make_unique<DrawingProgramLayerFolder>();
|
|
|
|
|
o->folderData->folderList = o.get_obj_man()->read_create_message<NetworkingObjects::NetObjOrderedList<DrawingProgramLayerListItem>>(a, c);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
o->layerData = std::make_unique<DrawingProgramLayer>();
|
|
|
|
|
o->layerData->components = o.get_obj_man()->read_create_message<CanvasComponentContainer::NetList>(a, c);
|
|
|
|
|
}
|
|
|
|
|
o->nameData = o.get_obj_man()->read_create_message<NameData>(a, c);
|
|
|
|
|
o->displayData = o.get_obj_man()->read_create_message<DisplayData>(a, c);
|
|
|
|
|
}
|