Translation works on selection
This commit is contained in:
parent
ff1355234f
commit
759f551cd3
9 changed files with 119 additions and 55 deletions
|
|
@ -22,19 +22,7 @@
|
|||
#include "../World.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include <execution>
|
||||
#ifdef __APPLE__
|
||||
#define POOLSTL_STD_SUPPLEMENT
|
||||
#include <poolstl.hpp>
|
||||
#endif
|
||||
|
||||
template <typename ContainerType> void parallel_loop_container(ContainerType& c, std::function<void(typename ContainerType::value_type&)> func) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
std::for_each(c.begin(), c.end(), func);
|
||||
#else
|
||||
std::for_each(std::execution::par_unseq, c.begin(), c.end(), func);
|
||||
#endif
|
||||
}
|
||||
#include <Helpers/Parallel.hpp>
|
||||
|
||||
DrawingProgram::DrawingProgram(World& initWorld):
|
||||
world(initWorld),
|
||||
|
|
@ -444,7 +432,6 @@ void DrawingProgram::reset_tools() {
|
|||
ellipseDrawTool.reset_tool();
|
||||
editTool.reset_tool();
|
||||
eraserTool.reset_tool();
|
||||
reset_selection();
|
||||
}
|
||||
|
||||
void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a) {
|
||||
|
|
@ -464,11 +451,6 @@ void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a)
|
|||
compCache.force_rebuild(components.client_list());
|
||||
}
|
||||
|
||||
void DrawingProgram::reset_selection() {
|
||||
for(auto& c : components.client_list())
|
||||
c->obj->selected = false;
|
||||
}
|
||||
|
||||
void DrawingProgram::add_undo_place_component(uint64_t placement, const std::shared_ptr<DrawComponent>& comp) {
|
||||
world.undo.push(UndoManager::UndoRedoPair{
|
||||
[&, comp]() {
|
||||
|
|
@ -573,8 +555,9 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
drawProgCacheCanvas->clear(SkColor4f{0.0f, 0.0f, 0.0f, 0.0f});
|
||||
compCache.refresh_all_draw_cache(drawData);
|
||||
compCache.draw_components_to_canvas(drawProgCacheCanvas, drawData);
|
||||
selection.draw_components(drawProgCacheCanvas, drawData);
|
||||
canvas->drawImage(world.main.drawProgCache.surface->makeTemporaryImage(), 0, 0);
|
||||
selection.draw(canvas, drawData);
|
||||
selection.draw_gui(canvas, drawData);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@ class DrawingProgram {
|
|||
|
||||
void add_file_to_canvas_by_path_execute(const std::string& filePath, Vector2f dropPos);
|
||||
|
||||
void reset_selection();
|
||||
void reset_tools();
|
||||
|
||||
void drag_drop_update();
|
||||
|
|
@ -135,4 +134,5 @@ class DrawingProgram {
|
|||
friend class EditTool;
|
||||
friend class ImageTool;
|
||||
friend class DrawingProgramCache;
|
||||
friend class DrawingProgramSelection;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
#include "DrawingProgram.hpp"
|
||||
#include "../World.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include <Helpers/MathExtras.hpp>
|
||||
#include <Helpers/SCollision.hpp>
|
||||
#include <Helpers/Parallel.hpp>
|
||||
|
||||
DrawingProgramSelection::DrawingProgramSelection(DrawingProgram& initDrawP):
|
||||
cache(initDrawP),
|
||||
|
|
@ -56,21 +59,24 @@ bool DrawingProgramSelection::is_something_selected() {
|
|||
|
||||
void DrawingProgramSelection::calculate_aabb() {
|
||||
if(is_something_selected()) {
|
||||
selectionAABB = (*selectedSet.begin())->obj->worldAABB.value();
|
||||
initialSelectionAABB = (*selectedSet.begin())->obj->worldAABB.value();
|
||||
for(auto& c : selectedSet)
|
||||
selectionAABB.include_aabb_in_bounds(c->obj->worldAABB.value());
|
||||
initialSelectionAABB.include_aabb_in_bounds(c->obj->worldAABB.value());
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::deselect_all() {
|
||||
for(auto& obj : selectedSet) {
|
||||
obj->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(obj->obj->coords);
|
||||
obj->obj->final_update(drawP);
|
||||
if(is_something_selected()) {
|
||||
std::vector<CollabListType::ObjectInfoPtr> a(selectedSet.begin(), selectedSet.end());
|
||||
parallel_loop_container(a, [&](auto& obj) {
|
||||
obj->obj->coords = selectionTransformCoords.other_coord_space_from_this_space(obj->obj->coords);
|
||||
obj->obj->final_update(drawP, false);
|
||||
});
|
||||
selectedSet.clear();
|
||||
cache.clear();
|
||||
selectionTransformCoords = CoordSpaceHelper();
|
||||
drawP.compCache.force_rebuild(drawP.components.client_list());
|
||||
}
|
||||
selectedSet.clear();
|
||||
cache.clear();
|
||||
selectionTransformCoords = CoordSpaceHelper();
|
||||
drawP.compCache.force_rebuild(drawP.components.client_list());
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::update() {
|
||||
|
|
@ -79,26 +85,39 @@ void DrawingProgramSelection::update() {
|
|||
cache.force_rebuild(std::vector<CollabListType::ObjectInfoPtr>(selectedSet.begin(), selectedSet.end()));
|
||||
if(drawP.world.main.input.key(InputManager::KEY_DRAW_UNSELECT).pressed)
|
||||
deselect_all();
|
||||
if(drawP.world.main.input.key(InputManager::KEY_TEXT_UP).held)
|
||||
selectionTransformCoords.translate(WorldVec{0, -drawP.world.drawData.cam.c.inverseScale});
|
||||
if(drawP.world.main.input.key(InputManager::KEY_TEXT_DOWN).held)
|
||||
selectionTransformCoords.translate(WorldVec{0, drawP.world.drawData.cam.c.inverseScale});
|
||||
if(drawP.world.main.input.key(InputManager::KEY_TEXT_LEFT).held)
|
||||
selectionTransformCoords.translate(WorldVec{-drawP.world.drawData.cam.c.inverseScale, 0});
|
||||
if(drawP.world.main.input.key(InputManager::KEY_TEXT_RIGHT).held)
|
||||
selectionTransformCoords.translate(WorldVec{drawP.world.drawData.cam.c.inverseScale, 0});
|
||||
if(drawP.world.main.input.key(InputManager::KEY_TEXT_CTRL).held)
|
||||
selectionTransformCoords.scale_about_double(selectionTransformCoords.pos, 1.01);
|
||||
if(drawP.world.main.input.key(InputManager::KEY_TEXT_SHIFT).held)
|
||||
selectionTransformCoords.scale_about_double(selectionTransformCoords.pos, 0.99);
|
||||
|
||||
selectionRectMin = selectionTransformCoords.from_space_world(initialSelectionAABB.min);
|
||||
selectionRectMax = selectionTransformCoords.from_space_world(initialSelectionAABB.max);
|
||||
|
||||
rebuild_cam_space();
|
||||
if(drawP.controls.leftClick && mouse_collided_with_selection_aabb())
|
||||
translation.happening = true;
|
||||
else if(drawP.controls.leftClickHeld && translation.happening)
|
||||
selectionTransformCoords.translate(drawP.world.drawData.cam.c.dir_from_space(drawP.world.main.input.mouse.move));
|
||||
else
|
||||
translation.happening = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool DrawingProgramSelection::mouse_collided_with_selection_aabb() {
|
||||
return false;
|
||||
void DrawingProgramSelection::rebuild_cam_space() {
|
||||
std::array<WorldVec, 4> collideRectTriangleVerticesWorld = triangle_from_rect_points(selectionRectMin, selectionRectMax);
|
||||
SCollision::ColliderCollection<WorldScalar> collideRectWorld;
|
||||
collideRectWorld.triangle.emplace_back(collideRectTriangleVerticesWorld[0], collideRectTriangleVerticesWorld[1], collideRectTriangleVerticesWorld[2]);
|
||||
collideRectWorld.triangle.emplace_back(collideRectTriangleVerticesWorld[0], collideRectTriangleVerticesWorld[2], collideRectTriangleVerticesWorld[3]);
|
||||
collideRectWorld.recalculate_bounds();
|
||||
|
||||
camSpaceSelection = drawP.world.drawData.cam.c.world_collider_to_coords<SCollision::ColliderCollection<float>>(collideRectWorld);
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
bool DrawingProgramSelection::mouse_collided_with_selection_aabb() {
|
||||
return SCollision::collide(camSpaceSelection, drawP.world.main.input.mouse.pos);
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::draw_components(SkCanvas* canvas, const DrawData& drawData) {
|
||||
if(is_something_selected()) {
|
||||
DrawData selectionDrawData = drawData;
|
||||
selectionDrawData.cam.c = selectionTransformCoords.other_coord_space_to_this_space(selectionDrawData.cam.c);
|
||||
|
|
@ -107,13 +126,20 @@ void DrawingProgramSelection::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
|
||||
cache.refresh_all_draw_cache(selectionDrawData);
|
||||
cache.draw_components_to_canvas(canvas, selectionDrawData);
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::draw_gui(SkCanvas* canvas, const DrawData& drawData) {
|
||||
if(is_something_selected() && !camSpaceSelection.triangle.empty()) {
|
||||
canvas->save();
|
||||
selectionTransformCoords.transform_sk_canvas(canvas, selectionDrawData);
|
||||
Vector2f minRectPos = selectionTransformCoords.to_space(selectionAABB.min);
|
||||
Vector2f maxRectPos = selectionTransformCoords.to_space(selectionAABB.max);
|
||||
SkPaint p{SkColor4f{0.0f, 0.0f, 1.0f, 0.3f}};
|
||||
canvas->drawRect(SkRect::MakeLTRB(minRectPos.x(), minRectPos.y(), maxRectPos.x(), maxRectPos.y()), p);
|
||||
SkPath selectionRectPath;
|
||||
selectionRectPath.moveTo(convert_vec2<SkPoint>(camSpaceSelection.triangle[0].p[0]));
|
||||
selectionRectPath.lineTo(convert_vec2<SkPoint>(camSpaceSelection.triangle[0].p[1]));
|
||||
selectionRectPath.lineTo(convert_vec2<SkPoint>(camSpaceSelection.triangle[0].p[2]));
|
||||
selectionRectPath.lineTo(convert_vec2<SkPoint>(camSpaceSelection.triangle[1].p[2]));
|
||||
selectionRectPath.close();
|
||||
SkPaint p{SkColor4f{0.3f, 0.6f, 0.9f, 0.4f}};
|
||||
canvas->drawPath(selectionRectPath, p);
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,15 +9,26 @@ class DrawingProgramSelection {
|
|||
void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC);
|
||||
void deselect_all();
|
||||
void update();
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData);
|
||||
void draw_components(SkCanvas* canvas, const DrawData& drawData);
|
||||
void draw_gui(SkCanvas* canvas, const DrawData& drawData);
|
||||
bool is_something_selected();
|
||||
bool mouse_collided_with_selection_aabb();
|
||||
private:
|
||||
void calculate_aabb();
|
||||
bool mouse_collided_with_selection_aabb();
|
||||
void rebuild_cam_space();
|
||||
|
||||
SCollision::AABB<WorldScalar> initialSelectionAABB;
|
||||
SCollision::ColliderCollection<float> camSpaceSelection;
|
||||
|
||||
WorldVec selectionRectMin;
|
||||
WorldVec selectionRectMax;
|
||||
|
||||
SCollision::AABB<WorldScalar> selectionAABB;
|
||||
CoordSpaceHelper selectionTransformCoords;
|
||||
std::unordered_set<CollabListType::ObjectInfoPtr> selectedSet;
|
||||
DrawingProgramCache cache;
|
||||
DrawingProgram& drawP;
|
||||
|
||||
struct TranslationData {
|
||||
bool happening = false;
|
||||
} translation;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -33,7 +33,9 @@ void RectSelectTool::gui_toolbox() {
|
|||
}
|
||||
|
||||
void RectSelectTool::reset_tool() {
|
||||
drawP.selection.deselect_all();
|
||||
controls = RectSelectControls();
|
||||
drawP.compCache.disableRefresh = false;
|
||||
}
|
||||
|
||||
void RectSelectTool::tool_update() {
|
||||
|
|
@ -41,10 +43,16 @@ void RectSelectTool::tool_update() {
|
|||
case 0: {
|
||||
drawP.compCache.disableRefresh = false;
|
||||
if(drawP.controls.leftClick) {
|
||||
reset_tool();
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.selectStartAt = controls.coords.get_mouse_pos(drawP.world);
|
||||
controls.selectionMode = 1;
|
||||
if(drawP.selection.is_something_selected()) {
|
||||
if(!drawP.selection.mouse_collided_with_selection_aabb())
|
||||
reset_tool();
|
||||
}
|
||||
else {
|
||||
reset_tool();
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.selectStartAt = controls.coords.get_mouse_pos(drawP.world);
|
||||
controls.selectionMode = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -62,6 +70,7 @@ void RectSelectTool::tool_update() {
|
|||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
|
||||
controls.selectionMode = 0;
|
||||
drawP.compCache.disableRefresh = true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue