Fixed selected object ordering
This commit is contained in:
parent
9d752af00c
commit
b688c39e68
6 changed files with 52 additions and 68 deletions
|
|
@ -348,9 +348,8 @@ void DrawingProgram::rebuild_cache() {
|
|||
EraserTool* eraserTool = static_cast<EraserTool*>(drawTool.get());
|
||||
drawCache.build(eraserTool->erasedComponents);
|
||||
}
|
||||
else if(is_selection_allowing_tool(drawTool->get_type())) {
|
||||
drawCache.build(selection.get_selected_set());
|
||||
}
|
||||
else if(is_selection_allowing_tool(drawTool->get_type()))
|
||||
drawCache.build(selection.get_selection_as_set());
|
||||
else
|
||||
drawCache.build({});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,11 @@ DrawingProgramSelection::DrawingProgramSelection(DrawingProgram& initDrawP):
|
|||
{}
|
||||
|
||||
void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC, DrawingProgramLayerManager::LayerSelector layerSelector, bool frontObjectOnly) {
|
||||
std::unordered_set<CanvasComponentContainer::ObjInfo*> selectedComponents;
|
||||
std::vector<CanvasComponentContainer::ObjInfo*> selectedComponents;
|
||||
if(frontObjectOnly) {
|
||||
CanvasComponentContainer::ObjInfo* a = drawP.drawCache.get_front_object_colliding_with_in_editing_layer(cC);
|
||||
if(a) {
|
||||
selectedComponents.emplace(a);
|
||||
selectedComponents.emplace_back(a);
|
||||
drawP.drawCache.erase_component(a);
|
||||
}
|
||||
}
|
||||
|
|
@ -43,7 +43,7 @@ void DrawingProgramSelection::remove_from_cam_coord_collider_to_selection(const
|
|||
CanvasComponentContainer::ObjInfo* p = get_front_object_colliding_with_in_editing_layer(cC);
|
||||
if(p) {
|
||||
drawP.drawCache.add_component(p);
|
||||
selectedSet.erase(p);
|
||||
std::erase(selectedSet, p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -60,7 +60,7 @@ void DrawingProgramSelection::remove_from_cam_coord_collider_to_selection(const
|
|||
calculate_aabb();
|
||||
}
|
||||
|
||||
std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> DrawingProgramSelection::erase_select_objects_in_bvh_func(std::unordered_set<CanvasComponentContainer::ObjInfo*>& selectedComponents, const SCollision::ColliderCollection<float>& cC, const SCollision::ColliderCollection<WorldScalar>& cCWorld, DrawingProgramLayerManager::LayerSelector layerSelector) {
|
||||
std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> DrawingProgramSelection::erase_select_objects_in_bvh_func(std::vector<CanvasComponentContainer::ObjInfo*>& selectedComponents, const SCollision::ColliderCollection<float>& cC, const SCollision::ColliderCollection<WorldScalar>& cCWorld, DrawingProgramLayerManager::LayerSelector layerSelector) {
|
||||
auto toRet = [&](const auto& bvhNode) {
|
||||
if(bvhNode && (bvhNode->coords.inverseScale << 9) < drawP.world.drawData.cam.c.inverseScale &&
|
||||
SCollision::collide(cC, drawP.world.drawData.cam.c.to_space(bvhNode->bounds.min)) &&
|
||||
|
|
@ -71,7 +71,7 @@ std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> DrawingP
|
|||
drawP.drawCache.traverse_bvh_run_function_starting_at_node_no_collision_check(bvhNode, [&](const auto& bvhNodeChild) {
|
||||
drawP.drawCache.node_loop_erase_if_components(bvhNodeChild, [&](auto c) {
|
||||
if(drawP.layerMan.component_passes_layer_selector(c, drawP.controls.layerSelector)) {
|
||||
selectedComponents.emplace(c);
|
||||
selectedComponents.emplace_back(c);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -82,7 +82,7 @@ std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> DrawingP
|
|||
}
|
||||
drawP.drawCache.node_loop_erase_if_components(bvhNode, [&](auto c) {
|
||||
if(drawP.layerMan.component_passes_layer_selector(c, drawP.controls.layerSelector) && c->obj->collides_with(drawP.world.drawData.cam.c, cCWorld, cC)) {
|
||||
selectedComponents.emplace(c);
|
||||
selectedComponents.emplace_back(c);
|
||||
drawP.drawCache.invalidate_cache_at_aabb(c->obj->get_world_bounds());
|
||||
return true;
|
||||
}
|
||||
|
|
@ -94,16 +94,28 @@ std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> DrawingP
|
|||
return toRet;
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::add_to_selection(const std::unordered_set<CanvasComponentContainer::ObjInfo*>& newSelection) {
|
||||
selectedSet.insert(newSelection.begin(), newSelection.end());
|
||||
void DrawingProgramSelection::add_to_selection(const std::vector<CanvasComponentContainer::ObjInfo*>& newSelection) {
|
||||
selectedSet.insert(selectedSet.end(), newSelection.begin(), newSelection.end());
|
||||
sort_selection();
|
||||
calculate_aabb();
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::set_to_selection(const std::unordered_set<CanvasComponentContainer::ObjInfo*>& newSelection) {
|
||||
void DrawingProgramSelection::set_to_selection(const std::vector<CanvasComponentContainer::ObjInfo*>& newSelection) {
|
||||
selectedSet = newSelection;
|
||||
sort_selection();
|
||||
calculate_aabb();
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::sort_selection() {
|
||||
std::vector<DrawingProgramLayerListItem*> flattenedLayerList = drawP.layerMan.get_flattened_layer_list();
|
||||
std::unordered_map<DrawingProgramLayerListItem*, size_t> flattenedLayerListOrder;
|
||||
for(size_t i = 0; i < flattenedLayerList.size(); i++)
|
||||
flattenedLayerListOrder[flattenedLayerList[i]] = i;
|
||||
std::sort(selectedSet.begin(), selectedSet.end(), [&](auto& a, auto& b) {
|
||||
return (flattenedLayerListOrder[a->obj->parentLayer] < flattenedLayerListOrder[b->obj->parentLayer]) || (a->obj->parentLayer == b->obj->parentLayer && a->pos < b->pos);
|
||||
});
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::calculate_aabb() {
|
||||
if(is_something_selected()) {
|
||||
initialSelectionAABB = (*selectedSet.begin())->obj->get_world_bounds();
|
||||
|
|
@ -118,7 +130,7 @@ bool DrawingProgramSelection::is_something_selected() {
|
|||
}
|
||||
|
||||
bool DrawingProgramSelection::is_selected(CanvasComponentContainer::ObjInfo* objToCheck) {
|
||||
return selectedSet.contains(objToCheck);
|
||||
return std::find(selectedSet.begin(), selectedSet.end(), objToCheck) != selectedSet.end();
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::reset_all() {
|
||||
|
|
@ -292,13 +304,13 @@ void DrawingProgramSelection::delete_all() {
|
|||
if(is_something_selected()) {
|
||||
auto selectedSetTemp = selectedSet;
|
||||
reset_all(); // Clear set before erasing, since calling erase_component_set will run a check to see if each object is selected and erase them one by one, which is slower
|
||||
drawP.layerMan.erase_component_set(selectedSetTemp);
|
||||
drawP.layerMan.erase_component_container(selectedSetTemp);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::erase_component(CanvasComponentContainer::ObjInfo* objToCheck) {
|
||||
if(is_selected(objToCheck)) {
|
||||
selectedSet.erase(objToCheck);
|
||||
std::erase(selectedSet, objToCheck);
|
||||
if(selectedSet.empty())
|
||||
reset_all();
|
||||
}
|
||||
|
|
@ -319,16 +331,8 @@ void DrawingProgramSelection::selection_to_clipboard() {
|
|||
std::unordered_set<NetworkingObjects::NetObjID> resourceSet;
|
||||
for(auto& c : selectedSet)
|
||||
c->obj->get_comp().get_used_resources(resourceSet);
|
||||
std::vector<CanvasComponentContainer::ObjInfo*> compVecSort(selectedSet.begin(), selectedSet.end());
|
||||
std::vector<DrawingProgramLayerListItem*> flattenedLayerList = drawP.layerMan.get_flattened_layer_list();
|
||||
std::unordered_map<DrawingProgramLayerListItem*, size_t> flattenedLayerListOrder;
|
||||
for(size_t i = 0; i < flattenedLayerList.size(); i++)
|
||||
flattenedLayerListOrder[flattenedLayerList[i]] = i;
|
||||
std::sort(compVecSort.begin(), compVecSort.end(), [&](auto& a, auto& b) {
|
||||
return (flattenedLayerListOrder[a->obj->parentLayer] < flattenedLayerListOrder[b->obj->parentLayer]) || (a->obj->parentLayer == b->obj->parentLayer && a->pos < b->pos);
|
||||
});
|
||||
clipboard.components.clear();
|
||||
for(auto& c : compVecSort)
|
||||
for(auto& c : selectedSet)
|
||||
clipboard.components.emplace_back(c->obj->get_data_copy());
|
||||
clipboard.pos = initialSelectionAABB.center();
|
||||
clipboard.inverseScale = drawP.world.drawData.cam.c.inverseScale;
|
||||
|
|
@ -365,9 +369,11 @@ void DrawingProgramSelection::paste_clipboard(Vector2f pasteScreenPos) {
|
|||
placedComponents.emplace_back(drawP.layerMan.get_edited_layer_end_iterator(), newComponentContainer);
|
||||
}
|
||||
auto newlyInsertedObjectIts = drawP.layerMan.add_many_components_to_layer_being_edited(placedComponents);
|
||||
std::unordered_set<CanvasComponentContainer::ObjInfo*> compSetInserted;
|
||||
for(auto& it : newlyInsertedObjectIts)
|
||||
compSetInserted.emplace(&(*it));
|
||||
std::vector<CanvasComponentContainer::ObjInfo*> compSetInserted;
|
||||
for(auto& it : newlyInsertedObjectIts) {
|
||||
drawP.drawCache.erase_component(&(*it));
|
||||
compSetInserted.emplace_back(&(*it));
|
||||
}
|
||||
set_to_selection(compSetInserted);
|
||||
//drawP.add_undo_place_components(compSetInserted);
|
||||
}
|
||||
|
|
@ -377,8 +383,8 @@ bool DrawingProgramSelection::is_being_transformed() {
|
|||
return transformOpHappening != TransformOperation::NONE;
|
||||
}
|
||||
|
||||
const std::unordered_set<CanvasComponentContainer::ObjInfo*>& DrawingProgramSelection::get_selected_set() {
|
||||
return selectedSet;
|
||||
std::unordered_set<CanvasComponentContainer::ObjInfo*> DrawingProgramSelection::get_selection_as_set() {
|
||||
return std::unordered_set<CanvasComponentContainer::ObjInfo*>(selectedSet.begin(), selectedSet.end());
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::rebuild_cam_space() {
|
||||
|
|
@ -422,7 +428,8 @@ void DrawingProgramSelection::draw_components(SkCanvas* canvas, const DrawData&
|
|||
if(!surface)
|
||||
throw std::runtime_error("[DrawingProgramSelection::draw_components] Could not make temporary surface");
|
||||
|
||||
draw_components_recursive(drawP.layerMan.get_layer_root(), surface->getCanvas(), selectionDrawData);
|
||||
for(auto& c : selectedSet)
|
||||
c->obj->draw(canvas, selectionDrawData);
|
||||
|
||||
SkPaint glowBlurP;
|
||||
glowBlurP.setImageFilter(SkImageFilters::Blur(5, 5, nullptr));
|
||||
|
|
@ -453,23 +460,3 @@ void DrawingProgramSelection::draw_gui(SkCanvas* canvas, const DrawData& drawDat
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::draw_components_recursive(const DrawingProgramLayerListItem& layerItem, SkCanvas* canvas, const DrawData& drawData) {
|
||||
if(layerItem.get_visible()) {
|
||||
SkPaint layerPaint;
|
||||
layerPaint.setAlphaf(layerItem.get_alpha());
|
||||
//layerPaint.setBlendMode(serialized_blend_mode_to_sk_blend_mode(displayData->blendMode)); // For selection, everything should just be in default blend mode (SrcOver)
|
||||
canvas->saveLayer(nullptr, &layerPaint);
|
||||
if(layerItem.is_folder()) {
|
||||
for(auto& p : *layerItem.get_folder().folderList | std::views::reverse)
|
||||
draw_components_recursive(*p.obj, canvas, drawData);
|
||||
}
|
||||
else {
|
||||
for(auto& c : selectedSet) { // Loop on selected set and not layer component list, since i'm assuming selected set will be small
|
||||
if(c->obj->parentLayer == &layerItem)
|
||||
c->obj->draw(canvas, drawData);
|
||||
}
|
||||
}
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,12 +19,11 @@ class DrawingProgramSelection {
|
|||
void update();
|
||||
void deselect_all();
|
||||
void paste_clipboard(Vector2f pasteScreenPos);
|
||||
const std::unordered_set<CanvasComponentContainer::ObjInfo*>& get_selected_set();
|
||||
std::unordered_set<CanvasComponentContainer::ObjInfo*> get_selection_as_set();
|
||||
void delete_all();
|
||||
void selection_to_clipboard();
|
||||
CanvasComponentContainer::ObjInfo* get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection<float>& cC);
|
||||
private:
|
||||
void draw_components_recursive(const DrawingProgramLayerListItem& layerItem, SkCanvas* canvas, const DrawData& drawData);
|
||||
bool mouse_collided_with_selection_aabb();
|
||||
bool mouse_collided_with_scale_point();
|
||||
bool mouse_collided_with_rotate_center_handle_point();
|
||||
|
|
@ -34,16 +33,17 @@ class DrawingProgramSelection {
|
|||
void rebuild_cam_space();
|
||||
Vector2f get_rotation_point_pos_from_angle(double angle);
|
||||
|
||||
void set_to_selection(const std::unordered_set<CanvasComponentContainer::ObjInfo*>& newSelection);
|
||||
void add_to_selection(const std::unordered_set<CanvasComponentContainer::ObjInfo*>& newSelection);
|
||||
void set_to_selection(const std::vector<CanvasComponentContainer::ObjInfo*>& newSelection);
|
||||
void add_to_selection(const std::vector<CanvasComponentContainer::ObjInfo*>& newSelection);
|
||||
void sort_selection();
|
||||
void calculate_aabb();
|
||||
void reset_all();
|
||||
std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> erase_select_objects_in_bvh_func(std::unordered_set<CanvasComponentContainer::ObjInfo*>& selectedComponents, const SCollision::ColliderCollection<float>& cC, const SCollision::ColliderCollection<WorldScalar>& cCWorld, DrawingProgramLayerManager::LayerSelector layerSelector);
|
||||
std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> erase_select_objects_in_bvh_func(std::vector<CanvasComponentContainer::ObjInfo*>& selectedComponents, const SCollision::ColliderCollection<float>& cC, const SCollision::ColliderCollection<WorldScalar>& cCWorld, DrawingProgramLayerManager::LayerSelector layerSelector);
|
||||
|
||||
SCollision::ColliderCollection<float> camSpaceSelection;
|
||||
std::array<WorldVec, 4> selectionRectPoints;
|
||||
CoordSpaceHelperTransform selectionTransformCoords;
|
||||
std::unordered_set<CanvasComponentContainer::ObjInfo*> selectedSet;
|
||||
std::vector<CanvasComponentContainer::ObjInfo*> selectedSet;
|
||||
SCollision::AABB<WorldScalar> initialSelectionAABB;
|
||||
DrawingProgram& drawP;
|
||||
|
||||
|
|
|
|||
|
|
@ -62,16 +62,6 @@ const DrawingProgramLayerListItem& DrawingProgramLayerManager::get_layer_root()
|
|||
return *layerTreeRoot;
|
||||
}
|
||||
|
||||
void DrawingProgramLayerManager::erase_component_set(const std::unordered_set<CanvasComponentContainer::ObjInfo*>& compsToErase) {
|
||||
std::unordered_map<DrawingProgramLayerListItem*, std::vector<CanvasComponentContainer::ObjInfoIterator>> idsToEraseInSpecificLayers;
|
||||
for(auto& c : compsToErase)
|
||||
idsToEraseInSpecificLayers[c->obj->parentLayer].emplace_back(c->obj->objInfo);
|
||||
for(auto& [layerListItem, netObjSetToErase] : idsToEraseInSpecificLayers) {
|
||||
auto& layerComponentList = layerListItem->get_layer().components;
|
||||
layerComponentList->erase_list(layerComponentList, netObjSetToErase);
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawingProgramLayerManager::component_passes_layer_selector(CanvasComponentContainer::ObjInfo* c, LayerSelector layerSelector) {
|
||||
switch(layerSelector) {
|
||||
case LayerSelector::ALL_VISIBLE_LAYERS:
|
||||
|
|
|
|||
|
|
@ -24,7 +24,15 @@ class DrawingProgramLayerManager {
|
|||
void write_components_server(cereal::PortableBinaryOutputArchive& a);
|
||||
void read_components_client(cereal::PortableBinaryInputArchive& a);
|
||||
bool is_a_layer_being_edited();
|
||||
void erase_component_set(const std::unordered_set<CanvasComponentContainer::ObjInfo*>& compsToErase);
|
||||
template <typename List> void erase_component_container(const List& compsToErase) {
|
||||
std::unordered_map<DrawingProgramLayerListItem*, std::vector<CanvasComponentContainer::ObjInfoIterator>> idsToEraseInSpecificLayers;
|
||||
for(auto& c : compsToErase)
|
||||
idsToEraseInSpecificLayers[c->obj->parentLayer].emplace_back(c->obj->objInfo);
|
||||
for(auto& [layerListItem, netObjSetToErase] : idsToEraseInSpecificLayers) {
|
||||
auto& layerComponentList = layerListItem->get_layer().components;
|
||||
layerComponentList->erase_list(layerComponentList, netObjSetToErase);
|
||||
}
|
||||
}
|
||||
uint32_t edited_layer_component_count();
|
||||
CanvasComponentContainer::ObjInfoIterator get_edited_layer_end_iterator();
|
||||
bool component_passes_layer_selector(CanvasComponentContainer::ObjInfo* c, LayerSelector layerSelector);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ void EraserTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp)
|
|||
}
|
||||
|
||||
void EraserTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
drawP.layerMan.erase_component_set(erasedComponents);
|
||||
drawP.layerMan.erase_component_container(erasedComponents);
|
||||
}
|
||||
|
||||
void EraserTool::tool_update() {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue