Can now add and remove from selection using shift and alt
This commit is contained in:
parent
137b1603e5
commit
1a5815a994
12 changed files with 103 additions and 61 deletions
|
|
@ -114,7 +114,7 @@ void DrawCamera::update_main(World& w) {
|
|||
}
|
||||
else {
|
||||
bool middleClickDown = w.main.input.mouse.middleDown || w.main.input.pen.buttons[w.main.toolbar.tabletOptions.middleClickButton].held;
|
||||
bool newIsMiddleClickZooming = middleClickDown && w.main.input.key(InputManager::KEY_ZOOM_CTRL).held;
|
||||
bool newIsMiddleClickZooming = middleClickDown && w.main.input.key(InputManager::KEY_GENERIC_LCTRL).held;
|
||||
if(newIsMiddleClickZooming && !isMiddleClickZooming) {
|
||||
startZoomMousePos = w.get_mouse_world_pos();
|
||||
startZoomVal = c.inverseScale;
|
||||
|
|
|
|||
|
|
@ -285,6 +285,7 @@ void DrawingProgram::update() {
|
|||
else if(world.main.input.key(InputManager::KEY_DRAW_TOOL_EDIT).pressed)
|
||||
switch_to_tool(DrawingProgramToolType::EDIT);
|
||||
|
||||
selection.update();
|
||||
drawTool->tool_update();
|
||||
|
||||
if(controls.leftClickReleased)
|
||||
|
|
@ -293,8 +294,6 @@ void DrawingProgram::update() {
|
|||
check_delayed_update_timers();
|
||||
check_updateable_components();
|
||||
|
||||
selection.update();
|
||||
|
||||
if(drawTool->get_type() == DrawingProgramToolType::ERASER) {
|
||||
EraserTool* eraserTool = static_cast<EraserTool*>(drawTool.get());
|
||||
compCache.test_rebuild_dont_include_set_dont_include_nodes(components.client_list(), eraserTool->erasedComponents, eraserTool->erasedBVHNodes);
|
||||
|
|
@ -312,7 +311,7 @@ void DrawingProgram::switch_to_tool_ptr(std::unique_ptr<DrawingProgramToolBase>
|
|||
|
||||
void DrawingProgram::switch_to_tool(DrawingProgramToolType newToolType) {
|
||||
if(newToolType != drawTool->get_type()) {
|
||||
drawTool->switch_tool(drawTool->get_type());
|
||||
drawTool->switch_tool(newToolType);
|
||||
drawTool = DrawingProgramToolBase::allocate_tool_type(*this, newToolType);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,11 +35,7 @@ void DrawingProgramSelection::erase_component(const CollabListType::ObjectInfoPt
|
|||
}
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC) {
|
||||
auto cCWorld = drawP.world.drawData.cam.c.collider_to_world<SCollision::ColliderCollection<WorldScalar>, SCollision::ColliderCollection<float>>(cC);
|
||||
|
||||
std::unordered_set<CollabListType::ObjectInfoPtr> selectedComponents;
|
||||
|
||||
std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&, std::vector<CollabListType::ObjectInfoPtr>&)> DrawingProgramSelection::erase_select_objects_in_bvh_func(std::unordered_set<CollabListType::ObjectInfoPtr>& selectedComponents, const SCollision::ColliderCollection<float>& cC, const SCollision::ColliderCollection<WorldScalar>& cCWorld) {
|
||||
std::function<void(const std::shared_ptr<DrawingProgramCacheBVHNode>&)> fullyCollidedFunc = [&](const std::shared_ptr<DrawingProgramCacheBVHNode>& bvhNode) {
|
||||
if(bvhNode) {
|
||||
for(auto& c : bvhNode->components)
|
||||
|
|
@ -48,7 +44,8 @@ void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCo
|
|||
fullyCollidedFunc(p);
|
||||
}
|
||||
};
|
||||
drawP.compCache.traverse_bvh_erase_function(cCWorld.bounds, [&](const auto& bvhNode, auto& comps) {
|
||||
|
||||
auto toRet = [&](const auto& bvhNode, auto& comps) {
|
||||
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)) &&
|
||||
SCollision::collide(cC, drawP.world.drawData.cam.c.to_space(bvhNode->bounds.max)) &&
|
||||
|
|
@ -67,9 +64,43 @@ void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCo
|
|||
return false;
|
||||
});
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
set_to_selection(selectedComponents);
|
||||
return toRet;
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC) {
|
||||
auto cCWorld = drawP.world.drawData.cam.c.collider_to_world<SCollision::ColliderCollection<WorldScalar>, SCollision::ColliderCollection<float>>(cC);
|
||||
std::unordered_set<CollabListType::ObjectInfoPtr> selectedComponents;
|
||||
drawP.compCache.traverse_bvh_erase_function(cCWorld.bounds, erase_select_objects_in_bvh_func(selectedComponents, cC, cCWorld));
|
||||
add_to_selection(selectedComponents);
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC) {
|
||||
auto cCWorld = drawP.world.drawData.cam.c.collider_to_world<SCollision::ColliderCollection<WorldScalar>, SCollision::ColliderCollection<float>>(cC);
|
||||
std::unordered_set<CollabListType::ObjectInfoPtr> selectedComponents;
|
||||
cache.traverse_bvh_erase_function(cCWorld.bounds, erase_select_objects_in_bvh_func(selectedComponents, cC, cCWorld));
|
||||
std::erase_if(selectedSet, [&](auto& c) {
|
||||
return selectedComponents.contains(c);
|
||||
});
|
||||
for(auto& obj : selectedComponents)
|
||||
drawP.compCache.add_component(obj);
|
||||
if(!is_something_selected()) {
|
||||
reset_selection_data();
|
||||
reset_transform_data();
|
||||
}
|
||||
else {
|
||||
calculate_aabb();
|
||||
calculate_initial_rotate_center_location();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::add_to_selection(const std::unordered_set<CollabListType::ObjectInfoPtr>& newSelection) {
|
||||
selectedSet.insert(newSelection.begin(), newSelection.end());
|
||||
for(auto& obj : newSelection)
|
||||
cache.add_component(obj);
|
||||
calculate_aabb();
|
||||
calculate_initial_rotate_center_location();
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::set_to_selection(const std::unordered_set<CollabListType::ObjectInfoPtr>& newSelection) {
|
||||
|
|
@ -235,7 +266,7 @@ void DrawingProgramSelection::update() {
|
|||
|
||||
switch(transformOpHappening) {
|
||||
case TransformOperation::NONE:
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.controls.leftClick && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) {
|
||||
if(mouse_collided_with_scale_point()) {
|
||||
scaleData.currentPos = scaleData.startPos = selectionTransformCoords.from_space_world(initialSelectionAABB.max);
|
||||
scaleData.centerPos = selectionTransformCoords.from_space_world(initialSelectionAABB.center());
|
||||
|
|
@ -251,8 +282,6 @@ void DrawingProgramSelection::update() {
|
|||
translateData.startPos = drawP.world.get_mouse_world_pos();
|
||||
transformOpHappening = TransformOperation::TRANSLATE;
|
||||
}
|
||||
else
|
||||
deselect_all();
|
||||
}
|
||||
break;
|
||||
case TransformOperation::TRANSLATE:
|
||||
|
|
@ -325,6 +354,10 @@ void DrawingProgramSelection::update() {
|
|||
paste_clipboard();
|
||||
}
|
||||
|
||||
bool DrawingProgramSelection::is_being_transformed() {
|
||||
return transformOpHappening != TransformOperation::NONE;
|
||||
}
|
||||
|
||||
void DrawingProgramSelection::paste_clipboard() {
|
||||
auto& clipboard = drawP.world.main.clipboard;
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ class DrawingProgramSelection {
|
|||
public:
|
||||
DrawingProgramSelection(DrawingProgram& initDrawP);
|
||||
void add_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC);
|
||||
void remove_from_cam_coord_collider_to_selection(const SCollision::ColliderCollection<float>& cC);
|
||||
|
||||
void deselect_all();
|
||||
void update();
|
||||
void draw_components(SkCanvas* canvas, const DrawData& drawData);
|
||||
|
|
@ -18,9 +20,13 @@ class DrawingProgramSelection {
|
|||
bool is_selected(const CollabListType::ObjectInfoPtr& objToCheck);
|
||||
const std::unordered_set<CollabListType::ObjectInfoPtr>& get_selected_set();
|
||||
|
||||
bool is_being_transformed();
|
||||
|
||||
void invalidate_cache_at_optional_aabb_before_pos(const std::optional<SCollision::AABB<WorldScalar>>& aabb, uint64_t placementToInvalidateAt);
|
||||
void preupdate_component(const CollabListType::ObjectInfoPtr& objToCheck);
|
||||
private:
|
||||
std::function<bool(const std::shared_ptr<DrawingProgramCacheBVHNode>&, std::vector<CollabListType::ObjectInfoPtr>&)> erase_select_objects_in_bvh_func(std::unordered_set<CollabListType::ObjectInfoPtr>& selectedComponents, const SCollision::ColliderCollection<float>& cC, const SCollision::ColliderCollection<WorldScalar>& cCWorld);
|
||||
|
||||
void delete_all();
|
||||
bool mouse_collided_with_selection_aabb();
|
||||
bool mouse_collided_with_scale_point();
|
||||
|
|
@ -28,7 +34,10 @@ class DrawingProgramSelection {
|
|||
bool mouse_collided_with_rotate_handle_point();
|
||||
void selection_to_clipboard();
|
||||
void paste_clipboard();
|
||||
|
||||
void set_to_selection(const std::unordered_set<CollabListType::ObjectInfoPtr>& newSelection);
|
||||
void add_to_selection(const std::unordered_set<CollabListType::ObjectInfoPtr>& newSelection);
|
||||
void add_erased_objects_back_to_cache(const std::unordered_set<CollabListType::ObjectInfoPtr>& erasedObjects);
|
||||
|
||||
void commit_transform_selection();
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ void EllipseDrawTool::tool_update() {
|
|||
if(drawP.controls.leftClickHeld) {
|
||||
controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now();
|
||||
Vector2f newPos = controls.intermediateItem->coords.get_mouse_pos(drawP.world);
|
||||
if(drawP.world.main.input.key(InputManager::KEY_EQUAL_DIMENSIONS).held) {
|
||||
if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) {
|
||||
float height = std::fabs(controls.startAt.y() - newPos.y());
|
||||
newPos.x() = controls.startAt.x() + (((newPos.x() - controls.startAt.x()) < 0.0f ? -1.0f : 1.0f) * height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,25 +42,18 @@ void LassoSelectTool::gui_toolbox() {
|
|||
}
|
||||
|
||||
void LassoSelectTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
drawP.selection.deselect_all();
|
||||
controls.lassoPoints.clear();
|
||||
controls = LassoSelectControls();
|
||||
if(newTool != DrawingProgramToolType::RECTSELECT && newTool != DrawingProgramToolType::LASSOSELECT)
|
||||
drawP.selection.deselect_all();
|
||||
}
|
||||
|
||||
void LassoSelectTool::tool_update() {
|
||||
switch(controls.selectionMode) {
|
||||
case 0: {
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.selection.is_something_selected()) {
|
||||
if(!drawP.selection.mouse_collided_with_selection())
|
||||
switch_tool(get_type());
|
||||
}
|
||||
else {
|
||||
switch_tool(get_type());
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.lassoPoints.emplace_back(controls.coords.get_mouse_pos(drawP.world));
|
||||
controls.selectionMode = 1;
|
||||
}
|
||||
if(drawP.controls.leftClick && !drawP.selection.is_being_transformed()) {
|
||||
controls = LassoSelectControls();
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.lassoPoints.emplace_back(controls.coords.get_mouse_pos(drawP.world));
|
||||
controls.selectionMode = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -91,12 +84,16 @@ void LassoSelectTool::tool_update() {
|
|||
|
||||
cC.recalculate_bounds();
|
||||
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
|
||||
controls.selectionMode = 0;
|
||||
if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held)
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held)
|
||||
drawP.selection.remove_from_cam_coord_collider_to_selection(cC);
|
||||
else {
|
||||
drawP.selection.deselect_all();
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
}
|
||||
}
|
||||
else
|
||||
switch_tool(get_type());
|
||||
controls.selectionMode = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ void RectDrawTool::tool_update() {
|
|||
if(drawP.controls.leftClickHeld) {
|
||||
controls.intermediateItem->lastUpdateTime = std::chrono::steady_clock::now();
|
||||
Vector2f newPos = controls.intermediateItem->coords.get_mouse_pos(drawP.world);
|
||||
if(drawP.world.main.input.key(InputManager::KEY_EQUAL_DIMENSIONS).held) {
|
||||
if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) {
|
||||
float height = std::fabs(controls.startAt.y() - newPos.y());
|
||||
newPos.x() = controls.startAt.x() + (((newPos.x() - controls.startAt.x()) < 0.0f ? -1.0f : 1.0f) * height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,24 +21,18 @@ void RectSelectTool::gui_toolbox() {
|
|||
}
|
||||
|
||||
void RectSelectTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
drawP.selection.deselect_all();
|
||||
controls = RectSelectControls();
|
||||
if(newTool != DrawingProgramToolType::RECTSELECT && newTool != DrawingProgramToolType::LASSOSELECT)
|
||||
drawP.selection.deselect_all();
|
||||
}
|
||||
|
||||
void RectSelectTool::tool_update() {
|
||||
switch(controls.selectionMode) {
|
||||
case 0: {
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.selection.is_something_selected()) {
|
||||
if(!drawP.selection.mouse_collided_with_selection())
|
||||
switch_tool(get_type());
|
||||
}
|
||||
else {
|
||||
switch_tool(get_type());
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.selectStartAt = controls.coords.get_mouse_pos(drawP.world);
|
||||
controls.selectionMode = 1;
|
||||
}
|
||||
if(drawP.controls.leftClick && !drawP.selection.is_being_transformed()) {
|
||||
controls = RectSelectControls();
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.selectStartAt = controls.coords.get_mouse_pos(drawP.world);
|
||||
controls.selectionMode = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -54,7 +48,14 @@ void RectSelectTool::tool_update() {
|
|||
cC.triangle.emplace_back(controls.newT[2], controls.newT[3], controls.newT[0]);
|
||||
cC.recalculate_bounds();
|
||||
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held)
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held)
|
||||
drawP.selection.remove_from_cam_coord_collider_to_selection(cC);
|
||||
else {
|
||||
drawP.selection.deselect_all();
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
}
|
||||
|
||||
controls.selectionMode = 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ class RectSelectTool : public DrawingProgramToolBase {
|
|||
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;
|
||||
virtual void switch_tool(DrawingProgramToolType newTool) override;
|
||||
virtual bool prevent_undo_or_redo() override;
|
||||
|
||||
private:
|
||||
struct RectSelectControls {
|
||||
int selectionMode = 0;
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ void TextBoxTool::tool_update() {
|
|||
}
|
||||
case 1: {
|
||||
Vector2f newPos = controls.intermediateItem->coords.get_mouse_pos(drawP.world);
|
||||
if(drawP.world.main.input.key(InputManager::KEY_EQUAL_DIMENSIONS).held) {
|
||||
if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) {
|
||||
float height = std::fabs(controls.startAt.y() - newPos.y());
|
||||
newPos.x() = controls.startAt.x() + (((newPos.x() - controls.startAt.x()) < 0.0f ? -1.0f : 1.0f) * height);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,13 +227,15 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) {
|
|||
set_key_down(e, KEY_TEXT_HOME);
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
set_key_down(e, KEY_ZOOM_SHIFT);
|
||||
set_key_down(e, KEY_TEXT_SHIFT);
|
||||
set_key_down(e, KEY_EQUAL_DIMENSIONS);
|
||||
set_key_down(e, KEY_GENERIC_LSHIFT);
|
||||
break;
|
||||
case SDLK_LALT:
|
||||
set_key_down(e, KEY_GENERIC_LALT);
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
set_key_down(e, KEY_TEXT_CTRL);
|
||||
set_key_down(e, KEY_ZOOM_CTRL);
|
||||
set_key_down(e, KEY_GENERIC_LCTRL);
|
||||
break;
|
||||
case SDLK_C:
|
||||
// Use either Ctrl or Meta (command for Mac) keys. We do either instead of checking, since checking can get complicated on Emscripten
|
||||
|
|
@ -297,13 +299,15 @@ void InputManager::backend_key_up_update(const SDL_KeyboardEvent& e) {
|
|||
set_key_up(e, KEY_TEXT_HOME);
|
||||
break;
|
||||
case SDLK_LSHIFT:
|
||||
set_key_up(e, KEY_ZOOM_SHIFT);
|
||||
set_key_up(e, KEY_TEXT_SHIFT);
|
||||
set_key_up(e, KEY_EQUAL_DIMENSIONS);
|
||||
set_key_up(e, KEY_GENERIC_LSHIFT);
|
||||
break;
|
||||
case SDLK_LALT:
|
||||
set_key_up(e, KEY_GENERIC_LALT);
|
||||
break;
|
||||
case SDLK_LCTRL:
|
||||
set_key_up(e, KEY_TEXT_CTRL);
|
||||
set_key_up(e, KEY_ZOOM_CTRL);
|
||||
set_key_up(e, KEY_GENERIC_LCTRL);
|
||||
break;
|
||||
case SDLK_C:
|
||||
set_key_up(e, KEY_TEXT_COPY);
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@ struct InputManager {
|
|||
KEY_TEXT_CTRL,
|
||||
KEY_TEXT_SELECTALL,
|
||||
KEY_TEXT_ESCAPE,
|
||||
KEY_ZOOM_SHIFT,
|
||||
KEY_ZOOM_CTRL,
|
||||
KEY_EQUAL_DIMENSIONS,
|
||||
KEY_GENERIC_LSHIFT,
|
||||
KEY_GENERIC_LALT,
|
||||
KEY_GENERIC_LCTRL,
|
||||
KEY_COUNT
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue