infinipaint/src/GridManager.cpp

172 lines
6.1 KiB
C++
Raw Normal View History

2025-07-06 20:43:53 +03:00
#include "GridManager.hpp"
#include "Server/CommandList.hpp"
#include "SharedTypes.hpp"
#include "World.hpp"
2025-09-17 17:17:43 +03:00
#include "MainProgram.hpp"
#include <algorithm>
2025-07-06 20:43:53 +03:00
2025-09-06 19:06:30 +03:00
GridManager::GridManager(World& w):
world(w) {}
2025-07-06 20:43:53 +03:00
2025-09-06 19:06:30 +03:00
void GridManager::init_client_callbacks() {
world.con.client_add_recv_callback(CLIENT_SET_GRID, [&](cereal::PortableBinaryInputArchive& message) {
ServerClientID gID;
message(gID);
auto& g = grids[gID];
message(g);
changed = true;
});
world.con.client_add_recv_callback(CLIENT_REMOVE_GRID, [&](cereal::PortableBinaryInputArchive& message) {
ServerClientID gID;
message(gID);
grids.erase(gID);
changed = true;
});
2025-09-06 19:06:30 +03:00
}
2025-07-06 20:43:53 +03:00
ServerClientID GridManager::add_default_grid(const std::string& newName) {
ServerClientID newID = world.get_new_id();
2025-09-06 19:06:30 +03:00
WorldGrid g;
g.name = newName;
g.color = color_mul_alpha(convert_vec4<Vector4f>(world.canvasTheme.toolFrontColor), 0.4f);
2025-09-17 17:17:43 +03:00
g.size = world.drawData.cam.c.inverseScale * WorldScalar(WorldGrid::GRID_UNIT_PIXEL_SIZE);
g.offset = world.drawData.cam.c.pos + world.drawData.cam.c.dir_from_space(world.main.window.size.cast<float>() * 0.5f);
grids[newID] = g;
2025-11-16 12:40:56 +03:00
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, newID, g);
2025-09-06 19:06:30 +03:00
changed = true;
2025-11-16 12:40:56 +03:00
world.undo.push({[&world = world, &changed = changed, &grids = grids, newID]() {
grids.erase(newID);
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, newID);
changed = true;
return true;
},
[&world = world, &changed = changed, &grids = grids, g, newID]() {
grids[newID] = g;
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, newID, g);
changed = true;
return true;
}});
return newID;
2025-08-01 10:58:45 +03:00
}
2025-11-16 12:40:56 +03:00
void GridManager::send_grid_info(WorldGrid oldGrid, ServerClientID gridID) {
auto gridFoundIt = grids.find(gridID);
if(gridFoundIt != grids.end()) {
WorldGrid& g = gridFoundIt->second;
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, g);
2025-11-16 12:40:56 +03:00
world.undo.push({[&world = world, &changed = changed, &grids = grids, gridID, oldGrid]() {
auto gridFoundIt = grids.find(gridID);
if(gridFoundIt == grids.end())
return false;
gridFoundIt->second = oldGrid;
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, oldGrid);
changed = true;
return true;
},
[&world = world, &changed = changed, &grids = grids, gridID, g]() {
auto gridFoundIt = grids.find(gridID);
if(gridFoundIt == grids.end())
return false;
gridFoundIt->second = g;
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, gridID, g);
changed = true;
return true;
}});
changed = true;
}
}
void GridManager::remove_grid(ServerClientID idToRemove) {
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, idToRemove);
2025-09-06 19:06:30 +03:00
changed = true;
2025-11-16 12:40:56 +03:00
auto it = grids.find(idToRemove);
if(it == grids.end())
return;
WorldGrid g = it->second;
grids.erase(it);
world.undo.push({[&world = world, &changed = changed, &grids = grids, idToRemove, g]() {
grids[idToRemove] = g;
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_SET_GRID, idToRemove, g);
changed = true;
return true;
},
[&world = world, &changed = changed, &grids = grids, idToRemove]() {
grids.erase(idToRemove);
world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_REMOVE_GRID, idToRemove);
changed = true;
return true;
}});
2025-07-06 20:43:53 +03:00
}
const std::vector<ServerClientID>& GridManager::sorted_grid_ids() {
2025-09-06 19:06:30 +03:00
if(changed) {
sortedGridIDs.clear();
2025-09-06 19:06:30 +03:00
for(auto& [k, v] : grids)
sortedGridIDs.emplace_back(k);
std::sort(sortedGridIDs.begin(), sortedGridIDs.end(), [&](ServerClientID a, ServerClientID b) {
std::string nameA = grids[a].get_display_name();
std::string nameB = grids[b].get_display_name();
bool namesEqual = nameA == nameB;
return (!namesEqual && std::lexicographical_compare(nameA.begin(), nameA.end(), nameB.begin(), nameB.end())) || (namesEqual && a < b);
});
2025-09-06 19:06:30 +03:00
changed = false;
2025-07-06 20:43:53 +03:00
}
return sortedGridIDs;
2025-09-06 19:06:30 +03:00
}
2025-07-06 20:43:53 +03:00
ClientPortionID GridManager::get_max_id(ServerPortionID serverID) const {
ClientPortionID maxClientID = 0;
for(auto& p : grids) {
if(p.first.first == serverID)
maxClientID = std::max(maxClientID, p.first.second);
}
return maxClientID;
}
void GridManager::draw_back(SkCanvas* canvas, const DrawData& drawData) {
auto& sortedGridIDS = sorted_grid_ids();
for(ServerClientID id : sortedGridIDS) {
if(!grids[id].displayInFront)
grids[id].draw(*this, canvas, drawData);
}
}
void GridManager::draw_front(SkCanvas* canvas, const DrawData& drawData) {
auto& sortedGridIDS = sorted_grid_ids();
for(ServerClientID id : sortedGridIDS) {
if(grids[id].displayInFront)
grids[id].draw(*this, canvas, drawData);
}
}
void GridManager::draw_coordinates(SkCanvas* canvas, const DrawData& drawData) {
auto& sortedGridIDS = sorted_grid_ids();
Vector2f axisOffset{0.0f, 0.0f};
for(ServerClientID id : sortedGridIDS) {
auto& g = grids[id];
if(g.coordinatesWillBeDrawn && g.coordinatesAxisOnBounds) {
grids[id].draw_coordinates(canvas, drawData, axisOffset);
g.coordinatesWillBeDrawn = false;
}
}
for(ServerClientID id : sortedGridIDS) {
auto& g = grids[id];
if(g.coordinatesWillBeDrawn && !g.coordinatesAxisOnBounds)
grids[id].draw_coordinates(canvas, drawData, axisOffset);
g.coordinatesWillBeDrawn = false;
}
2025-07-06 20:43:53 +03:00
}
void GridManager::scale_up(const WorldScalar& scaleUpAmount) {
for(auto& [id, g] : grids) {
g.scale_up(scaleUpAmount);
}
}