Started work on new cache system for layers
This commit is contained in:
parent
783bb7dacb
commit
c2abccefc2
14 changed files with 234 additions and 19 deletions
|
|
@ -58,6 +58,7 @@ set(sources "src/main.cpp"
|
|||
"src/RichText/TextBox.cpp"
|
||||
"src/RichText/TextStyleModifier.cpp"
|
||||
"src/RichText/ParagraphStyleData.cpp"
|
||||
"src/DrawingProgram/DrawingProgramCacheNew.cpp"
|
||||
"src/DrawingProgram/DrawingProgramCache.cpp"
|
||||
"src/DrawingProgram/DrawingProgram.cpp"
|
||||
"src/DrawingProgram/DrawingProgramSelection.cpp"
|
||||
|
|
|
|||
141
src/DrawingProgram/DrawingProgramCacheNew.cpp
Normal file
141
src/DrawingProgram/DrawingProgramCacheNew.cpp
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
#include "DrawingProgramCacheNew.hpp"
|
||||
#include "DrawingProgram.hpp"
|
||||
|
||||
std::unordered_set<std::shared_ptr<DrawingProgramCacheNew::BVHNode>> DrawingProgramCacheNew::nodesWithCachedSurfaces;
|
||||
|
||||
DrawingProgramCacheNew::DrawingProgramCacheNew(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
{}
|
||||
|
||||
void DrawingProgramCacheNew::add_component(const CanvasComponentContainer::ObjInfoSharedPtr& c) {
|
||||
unsortedComponents.emplace_back(c);
|
||||
invalidate_cache_at_aabb(c->obj->get_world_bounds());
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& c) {
|
||||
auto it = objToBVHNode.find(c);
|
||||
if(it != objToBVHNode.end())
|
||||
objToBVHNode.erase(it);
|
||||
else
|
||||
std::erase(unsortedComponents, c);
|
||||
invalidate_cache_at_aabb(c->obj->get_world_bounds());
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::invalidate_cache_at_aabb(const SCollision::AABB<WorldScalar>& aabb) {
|
||||
std::for_each(nodesWithCachedSurfaces.begin(), nodesWithCachedSurfaces.end(), [&](auto& n) {
|
||||
if(n->drawCache.value().attachedCache == this && SCollision::collide(aabb, n->bounds)) {
|
||||
auto& dCache = n->drawCache.value();
|
||||
if(dCache.invalidBounds.has_value()) {
|
||||
auto& iBounds = dCache.invalidBounds.value();
|
||||
iBounds.include_aabb_in_bounds(aabb);
|
||||
}
|
||||
else
|
||||
dCache.invalidBounds = aabb;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool DrawingProgramCacheNew::should_rebuild() const {
|
||||
return (unsortedComponents.size() >= MINIMUM_COMPONENTS_TO_START_REBUILD);
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::build(const std::unordered_set<CanvasComponentContainer::ObjInfoSharedPtr>& objsToExclude) {
|
||||
internal_build(drawP.layerMan.get_flattened_component_list(), objsToExclude);
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::internal_build(std::vector<CanvasComponentContainer::ObjInfoSharedPtr> componentsToBuild, const std::unordered_set<CanvasComponentContainer::ObjInfoSharedPtr>& objsToNotInclude) {
|
||||
std::erase_if(componentsToBuild, [&objsToNotInclude](auto& c) {
|
||||
return objsToNotInclude.contains(c);
|
||||
});
|
||||
bvhRoot = std::make_shared<BVHNode>();
|
||||
unsortedComponents.clear();
|
||||
clear_own_cached_surfaces();
|
||||
build_bvh_node(bvhRoot, componentsToBuild);
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::clear_own_cached_surfaces() {
|
||||
std::erase_if(nodesWithCachedSurfaces, [&](auto& n) {
|
||||
if(n->drawCache.value().attachedCache == this) {
|
||||
n->drawCache = std::nullopt;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::preupdate_component(const CanvasComponentContainer::ObjInfoSharedPtr& c) {
|
||||
auto it = objToBVHNode.find(c);
|
||||
if(it != objToBVHNode.end()) {
|
||||
unsortedComponents.emplace_back(c);
|
||||
std::erase(it->second->components, c);
|
||||
}
|
||||
invalidate_cache_at_aabb(c->obj->get_world_bounds());
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::build_bvh_node(const std::shared_ptr<BVHNode>& bvhNode, const std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& components) {
|
||||
if(components.empty())
|
||||
return;
|
||||
|
||||
bvhNode->bounds = components.front()->obj->get_world_bounds();
|
||||
for(auto& c : components)
|
||||
bvhNode->bounds.include_aabb_in_bounds(c->obj->get_world_bounds());
|
||||
|
||||
build_bvh_node_coords_and_resolution(*bvhNode);
|
||||
|
||||
if(components.size() < MAXIMUM_COMPONENTS_IN_SINGLE_NODE) {
|
||||
bvhNode->components = components;
|
||||
for(auto& c : bvhNode->components)
|
||||
objToBVHNode.emplace(c, bvhNode);
|
||||
return;
|
||||
}
|
||||
|
||||
WorldVec boundsCenter = bvhNode->bounds.center();
|
||||
|
||||
std::array<std::vector<CanvasComponentContainer::ObjInfoSharedPtr>, 4> parts;
|
||||
|
||||
for(auto& c : components) {
|
||||
const auto& cAABB = c->obj->get_world_bounds();
|
||||
if(cAABB.min.x() < boundsCenter.x() && cAABB.max.x() < boundsCenter.x() && cAABB.min.y() < boundsCenter.y() && cAABB.max.y() < boundsCenter.y())
|
||||
parts[0].emplace_back(c);
|
||||
else if(cAABB.min.x() > boundsCenter.x() && cAABB.max.x() > boundsCenter.x() && cAABB.min.y() < boundsCenter.y() && cAABB.max.y() < boundsCenter.y())
|
||||
parts[1].emplace_back(c);
|
||||
else if(cAABB.min.x() < boundsCenter.x() && cAABB.max.x() < boundsCenter.x() && cAABB.min.y() > boundsCenter.y() && cAABB.max.y() > boundsCenter.y())
|
||||
parts[2].emplace_back(c);
|
||||
else if(cAABB.min.x() > boundsCenter.x() && cAABB.max.x() > boundsCenter.x() && cAABB.min.y() > boundsCenter.y() && cAABB.max.y() > boundsCenter.y())
|
||||
parts[3].emplace_back(c);
|
||||
else {
|
||||
bvhNode->components.emplace_back(c);
|
||||
objToBVHNode.emplace(c, bvhNode);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto& p : parts) {
|
||||
if(!p.empty())
|
||||
build_bvh_node(bvhNode->children.emplace_back(std::make_shared<BVHNode>()), p);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramCacheNew::build_bvh_node_coords_and_resolution(BVHNode& node) {
|
||||
// These are part of the draw cache data, but we're putting it out here, because:
|
||||
// - We dont have to recalculate it every time we refresh the cache
|
||||
// - Some of the data here is needed to determine whether to generate the cache in the first place
|
||||
|
||||
constexpr int MAX_DIMENSION_RESOLUTION = 2048;
|
||||
|
||||
WorldVec cacheBoundDim = node.bounds.dim();
|
||||
if(cacheBoundDim.x() > cacheBoundDim.y()) {
|
||||
node.resolution.x() = MAX_DIMENSION_RESOLUTION;
|
||||
node.resolution.y() = MAX_DIMENSION_RESOLUTION * static_cast<double>(cacheBoundDim.y() / cacheBoundDim.x());
|
||||
}
|
||||
else {
|
||||
node.resolution.y() = MAX_DIMENSION_RESOLUTION;
|
||||
node.resolution.x() = MAX_DIMENSION_RESOLUTION * static_cast<double>(cacheBoundDim.x() / cacheBoundDim.y());
|
||||
}
|
||||
node.coords.rotation = 0.0;
|
||||
node.coords.pos = node.bounds.min;
|
||||
// Not necessary, but we choose the number that had less operations done on it for more accuracy
|
||||
if(node.resolution.x() > node.resolution.y())
|
||||
node.coords.inverseScale = cacheBoundDim.x().divide_double(node.resolution.x());
|
||||
else
|
||||
node.coords.inverseScale = cacheBoundDim.y().divide_double(node.resolution.y());
|
||||
}
|
||||
46
src/DrawingProgram/DrawingProgramCacheNew.hpp
Normal file
46
src/DrawingProgram/DrawingProgramCacheNew.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
#include "../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
#include <unordered_map>
|
||||
|
||||
class DrawingProgramCacheNew {
|
||||
public:
|
||||
static constexpr size_t MINIMUM_COMPONENTS_TO_START_REBUILD = 1000;
|
||||
static constexpr size_t MAXIMUM_COMPONENTS_IN_SINGLE_NODE = 50;
|
||||
static constexpr size_t MAXIMUM_DRAW_CACHE_SURFACES = 40;
|
||||
|
||||
DrawingProgramCacheNew(DrawingProgram& initDrawP);
|
||||
void add_component(const CanvasComponentContainer::ObjInfoSharedPtr& c);
|
||||
void erase_component(const CanvasComponentContainer::ObjInfoSharedPtr& c);
|
||||
void clear_own_cached_surfaces();
|
||||
void preupdate_component(const CanvasComponentContainer::ObjInfoSharedPtr& c);
|
||||
void build(const std::unordered_set<CanvasComponentContainer::ObjInfoSharedPtr>& objsToExclude);
|
||||
bool should_rebuild() const;
|
||||
private:
|
||||
struct BVHNode {
|
||||
SCollision::AABB<WorldScalar> bounds;
|
||||
std::vector<CanvasComponentContainer::ObjInfoSharedPtr> components;
|
||||
std::vector<std::shared_ptr<BVHNode>> children;
|
||||
|
||||
CoordSpaceHelper coords;
|
||||
Vector2i resolution;
|
||||
struct DrawCacheData {
|
||||
sk_sp<SkSurface> surface;
|
||||
std::chrono::steady_clock::time_point lastRenderTime;
|
||||
DrawingProgramCacheNew* attachedCache;
|
||||
std::optional<SCollision::AABB<WorldScalar>> invalidBounds;
|
||||
};
|
||||
|
||||
std::optional<DrawCacheData> drawCache;
|
||||
};
|
||||
static std::unordered_set<std::shared_ptr<BVHNode>> nodesWithCachedSurfaces;
|
||||
|
||||
void internal_build(std::vector<CanvasComponentContainer::ObjInfoSharedPtr> componentsToBuild, const std::unordered_set<CanvasComponentContainer::ObjInfoSharedPtr>& objsToNotInclude);
|
||||
void invalidate_cache_at_aabb(const SCollision::AABB<WorldScalar>& aabb);
|
||||
void build_bvh_node(const std::shared_ptr<BVHNode>& bvhNode, const std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& components);
|
||||
void build_bvh_node_coords_and_resolution(BVHNode& node);
|
||||
|
||||
std::unordered_map<CanvasComponentContainer::ObjInfoSharedPtr, std::shared_ptr<BVHNode>> objToBVHNode;
|
||||
std::shared_ptr<BVHNode> bvhRoot;
|
||||
std::vector<CanvasComponentContainer::ObjInfoSharedPtr> unsortedComponents;
|
||||
DrawingProgram& drawP;
|
||||
};
|
||||
|
|
@ -3,20 +3,24 @@
|
|||
#include "../DrawingProgram.hpp"
|
||||
#include <Helpers/Parallel.hpp>
|
||||
|
||||
void DrawingProgramLayer::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
void DrawingProgramLayer::draw(SkCanvas* canvas, const DrawData& drawData) const {
|
||||
for(auto& p : components->get_data())
|
||||
p->obj->draw(canvas, drawData);
|
||||
}
|
||||
|
||||
void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) {
|
||||
void DrawingProgramLayer::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const {
|
||||
components->set_insert_callback([&](const CanvasComponentContainer::ObjInfoSharedPtr& c) {
|
||||
c->obj->set_owner_obj_info(c);
|
||||
c->obj->commit_update(layerMan.drawP); // Run commit update on insert so that world bounds are calculated
|
||||
});
|
||||
}
|
||||
|
||||
void DrawingProgramLayer::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) {
|
||||
void DrawingProgramLayer::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const {
|
||||
parallel_loop_container(components->get_data(), [&layerMan](auto& comp) {
|
||||
comp->obj->commit_update_dont_invalidate_cache(layerMan.drawP);
|
||||
});
|
||||
}
|
||||
|
||||
void DrawingProgramLayer::get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const {
|
||||
objList.insert(objList.begin(), components->get_data().begin(), components->get_data().end());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,9 +7,10 @@ class DrawingProgramLayerManager;
|
|||
|
||||
class DrawingProgramLayer {
|
||||
public:
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData);
|
||||
void set_component_list_callbacks(DrawingProgramLayerManager& layerMan);
|
||||
void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan);
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData) const;
|
||||
void set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const;
|
||||
void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const;
|
||||
void get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const;
|
||||
|
||||
CanvasComponentContainer::NetListOwnerPtr components;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@
|
|||
#include "DrawingProgramLayer.hpp"
|
||||
#include <Helpers/Parallel.hpp>
|
||||
|
||||
void DrawingProgramLayerFolder::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
void DrawingProgramLayerFolder::draw(SkCanvas* canvas, const DrawData& drawData) const {
|
||||
for(auto& p : folderList->get_data() | std::views::reverse)
|
||||
p->obj->draw(canvas, drawData);
|
||||
}
|
||||
|
||||
void DrawingProgramLayerFolder::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) {
|
||||
void DrawingProgramLayerFolder::set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const {
|
||||
folderList->set_insert_callback([&](auto& c) {
|
||||
c->obj->set_component_list_callbacks(layerMan);
|
||||
});
|
||||
|
|
@ -16,7 +16,12 @@ void DrawingProgramLayerFolder::set_component_list_callbacks(DrawingProgramLayer
|
|||
listItem->obj->set_component_list_callbacks(layerMan);
|
||||
}
|
||||
|
||||
void DrawingProgramLayerFolder::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) {
|
||||
void DrawingProgramLayerFolder::commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const {
|
||||
for(auto& listItem : folderList->get_data())
|
||||
listItem->obj->commit_update_dont_invalidate_cache(layerMan);
|
||||
}
|
||||
|
||||
void DrawingProgramLayerFolder::get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const {
|
||||
for(auto& listItem : folderList->get_data())
|
||||
listItem->obj->get_flattened_component_list(objList);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,17 @@
|
|||
#include <Helpers/NetworkingObjects/NetObjOrderedList.hpp>
|
||||
#include <include/core/SkCanvas.h>
|
||||
#include "../../DrawData.hpp"
|
||||
#include "../../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
|
||||
class DrawingProgramLayerListItem;
|
||||
class DrawingProgramLayerManager;
|
||||
|
||||
class DrawingProgramLayerFolder {
|
||||
public:
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData);
|
||||
void set_component_list_callbacks(DrawingProgramLayerManager& layerMan);
|
||||
void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan);
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData) const;
|
||||
void set_component_list_callbacks(DrawingProgramLayerManager& layerMan) const;
|
||||
void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan) const;
|
||||
void get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const;
|
||||
|
||||
NetworkingObjects::NetObjOwnerPtr<NetworkingObjects::NetObjOrderedList<DrawingProgramLayerListItem>> folderList;
|
||||
bool isFolderOpen = false;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,13 @@ void DrawingProgramLayerListItem::commit_update_dont_invalidate_cache(DrawingPro
|
|||
layerData->commit_update_dont_invalidate_cache(layerMan);
|
||||
}
|
||||
|
||||
void DrawingProgramLayerListItem::get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const {
|
||||
if(folderData)
|
||||
folderData->get_flattened_component_list(objList);
|
||||
else
|
||||
layerData->get_flattened_component_list(objList);
|
||||
}
|
||||
|
||||
bool DrawingProgramLayerListItem::is_folder() const {
|
||||
return folderData != nullptr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "DrawingProgramLayerFolder.hpp"
|
||||
#include "DrawingProgramLayer.hpp"
|
||||
#include "SerializedBlendMode.hpp"
|
||||
#include "../../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
|
||||
class DrawingProgramLayerFolder;
|
||||
class DrawingProgramLayer;
|
||||
|
|
@ -23,9 +24,9 @@ class DrawingProgramLayerListItem {
|
|||
void set_component_list_callbacks(DrawingProgramLayerManager &layerMan);
|
||||
void commit_update_dont_invalidate_cache(DrawingProgramLayerManager& layerMan);
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData) const;
|
||||
|
||||
void set_name(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, const std::string& newName) const;
|
||||
const std::string& get_name() const;
|
||||
void get_flattened_component_list(std::vector<CanvasComponentContainer::ObjInfoSharedPtr>& objList) const;
|
||||
|
||||
void set_alpha(NetworkingObjects::DelayUpdateSerializedClassManager& delayedNetObjMan, float newAlpha) const;
|
||||
float get_alpha() const;
|
||||
|
|
|
|||
|
|
@ -32,3 +32,9 @@ void DrawingProgramLayerManager::draw(SkCanvas* canvas, const DrawData& drawData
|
|||
if(layerTreeRoot)
|
||||
layerTreeRoot->draw(canvas, drawData);
|
||||
}
|
||||
|
||||
std::vector<CanvasComponentContainer::ObjInfoSharedPtr> DrawingProgramLayerManager::get_flattened_component_list() const {
|
||||
std::vector<CanvasComponentContainer::ObjInfoSharedPtr> toRet;
|
||||
layerTreeRoot->get_flattened_component_list(toRet);
|
||||
return toRet;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,6 @@ class DrawingProgramLayerManager {
|
|||
return nullptr;
|
||||
return editLayerPtr->get_layer().components->push_back_and_send_create(editLayerPtr->get_layer().components, newObj);
|
||||
}
|
||||
std::vector<CanvasComponentContainer::ObjInfoSharedPtr> get_flattened_component_list() const;
|
||||
DrawingProgramLayerManagerGUI listGUI;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ void EllipseDrawTool::switch_tool(DrawingProgramToolType newTool) {
|
|||
void EllipseDrawTool::tool_update() {
|
||||
switch(drawStage) {
|
||||
case 0: {
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.controls.leftClick && drawP.layerMan.is_a_layer_being_edited()) {
|
||||
CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::ELLIPSE);
|
||||
EllipseCanvasComponent& newEllipse = static_cast<EllipseCanvasComponent&>(newContainer->get_comp());
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ void EllipseDrawTool::tool_update() {
|
|||
newEllipse.d.fillStrokeMode = static_cast<uint8_t>(fillStrokeMode);
|
||||
newContainer->coords = drawP.world.drawData.cam.c;
|
||||
|
||||
objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newContainer);
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newContainer);
|
||||
drawStage = 1;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ void RectDrawTool::switch_tool(DrawingProgramToolType newTool) {
|
|||
void RectDrawTool::tool_update() {
|
||||
switch(drawStage) {
|
||||
case 0: {
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.controls.leftClick && drawP.layerMan.is_a_layer_being_edited()) {
|
||||
CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::RECTANGLE);
|
||||
RectangleCanvasComponent& newRectangle = static_cast<RectangleCanvasComponent&>(newContainer->get_comp());
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ void RectDrawTool::tool_update() {
|
|||
newRectangle.d.p2 = ensure_points_have_distance(newRectangle.d.p1, newRectangle.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS);
|
||||
newRectangle.d.fillStrokeMode = static_cast<uint8_t>(fillStrokeMode);
|
||||
newContainer->coords = drawP.world.drawData.cam.c;
|
||||
objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newContainer);
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newContainer);
|
||||
drawStage = 1;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ void TextBoxTool::switch_tool(DrawingProgramToolType newTool) {
|
|||
void TextBoxTool::tool_update() {
|
||||
switch(drawStage) {
|
||||
case 0: {
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.controls.leftClick && drawP.layerMan.is_a_layer_being_edited()) {
|
||||
startAt = drawP.world.main.input.mouse.pos;
|
||||
endAt = startAt;
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ void TextBoxTool::tool_update() {
|
|||
newTextBox.d.p2 = ensure_points_have_distance(newTextBox.d.p1, newTextBox.d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS);
|
||||
newTextBox.d.editing = true;
|
||||
newContainer->coords = drawP.world.drawData.cam.c;
|
||||
objInfoBeingEdited = drawP.components->push_back_and_send_create(drawP.components, newContainer);
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newContainer);
|
||||
drawStage = 1;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue