From 6285d6e5f54f1b11b9fb43402f15c175e876d405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gilles=20Roudi=C3=A8re?= Date: Tue, 17 Jan 2023 10:26:10 +0100 Subject: Fixes rectangle painting when dragging outside the atlas area --- editor/plugins/tiles/tile_atlas_view.cpp | 30 ++++++++++++------- editor/plugins/tiles/tile_atlas_view.h | 2 +- editor/plugins/tiles/tile_data_editors.cpp | 34 +++++++++++----------- editor/plugins/tiles/tile_map_editor.cpp | 8 ++--- .../plugins/tiles/tile_set_atlas_source_editor.cpp | 31 ++++++++++---------- 5 files changed, 57 insertions(+), 48 deletions(-) (limited to 'editor/plugins/tiles') diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp index 3c6ed0f049..0ac375407c 100644 --- a/editor/plugins/tiles/tile_atlas_view.cpp +++ b/editor/plugins/tiles/tile_atlas_view.cpp @@ -454,21 +454,31 @@ void TileAtlasView::set_padding(Side p_side, int p_padding) { margin_container_paddings[p_side] = p_padding; } -Vector2i TileAtlasView::get_atlas_tile_coords_at_pos(const Vector2 p_pos) const { +Vector2i TileAtlasView::get_atlas_tile_coords_at_pos(const Vector2 p_pos, bool p_clamp) const { Ref texture = tile_set_atlas_source->get_texture(); - if (texture.is_valid()) { - Vector2i margins = tile_set_atlas_source->get_margins(); - Vector2i separation = tile_set_atlas_source->get_separation(); - Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size(); + if (!texture.is_valid()) { + return TileSetSource::INVALID_ATLAS_COORDS; + } + + Vector2i margins = tile_set_atlas_source->get_margins(); + Vector2i separation = tile_set_atlas_source->get_separation(); + Vector2i texture_region_size = tile_set_atlas_source->get_texture_region_size(); - // Compute index in atlas - Vector2 pos = p_pos - margins; - Vector2i ret = (pos / (texture_region_size + separation)).floor(); + // Compute index in atlas + Vector2 pos = p_pos - margins; + Vector2i ret = (pos / (texture_region_size + separation)).floor(); - return ret; + // Return invalid value (without clamp). + Rect2i rect = Rect2(Vector2i(), tile_set_atlas_source->get_atlas_grid_size()); + if (!p_clamp && !rect.has_point(ret)) { + return TileSetSource::INVALID_ATLAS_COORDS; } - return TileSetSource::INVALID_ATLAS_COORDS; + // Clamp. + ret.x = CLAMP(ret.x, 0, rect.size.x - 1); + ret.y = CLAMP(ret.y, 0, rect.size.y - 1); + + return ret; } void TileAtlasView::_update_alternative_tiles_rect_cache() { diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h index 166abca2a3..f719bee704 100644 --- a/editor/plugins/tiles/tile_atlas_view.h +++ b/editor/plugins/tiles/tile_atlas_view.h @@ -128,7 +128,7 @@ public: void set_texture_grid_visible(bool p_visible) { base_tiles_texture_grid->set_visible(p_visible); }; void set_tile_shape_grid_visible(bool p_visible) { base_tiles_shape_grid->set_visible(p_visible); }; - Vector2i get_atlas_tile_coords_at_pos(const Vector2 p_pos) const; + Vector2i get_atlas_tile_coords_at_pos(const Vector2 p_pos, bool p_clamp = false) const; void add_control_over_atlas_tiles(Control *p_control, bool scaled = true) { if (scaled) { diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp index 966d394ca1..6a74bfba77 100644 --- a/editor/plugins/tiles/tile_data_editors.cpp +++ b/editor/plugins/tiles/tile_data_editors.cpp @@ -926,8 +926,8 @@ void TileDataDefaultEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas_ p_canvas_item->draw_set_transform_matrix(p_transform); Rect2i rect; - rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); - rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(p_transform.affine_inverse().xform(p_canvas_item->get_local_mouse_position()))); + rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos, true)); + rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(p_transform.affine_inverse().xform(p_canvas_item->get_local_mouse_position()), true)); rect = rect.abs(); RBSet edited; @@ -961,7 +961,7 @@ void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_ti Ref mm = p_event; if (mm.is_valid()) { if (drag_type == DRAG_TYPE_PAINT) { - Vector line = Geometry2D::bresenham_line(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_pos), p_tile_atlas_view->get_atlas_tile_coords_at_pos(mm->get_position())); + Vector line = Geometry2D::bresenham_line(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_pos, true), p_tile_atlas_view->get_atlas_tile_coords_at_pos(mm->get_position(), true)); for (int i = 0; i < line.size(); i++) { Vector2i coords = p_tile_set_atlas_source->get_tile_at_coords(line[i]); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { @@ -985,7 +985,7 @@ void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_ti if (mb->get_button_index() == MouseButton::LEFT) { if (mb->is_pressed()) { if (picker_button->is_pressed()) { - Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position()); + Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position(), true); coords = p_tile_set_atlas_source->get_tile_at_coords(coords); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { _set_painted_value(p_tile_set_atlas_source, coords, 0); @@ -1000,7 +1000,7 @@ void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_ti drag_type = DRAG_TYPE_PAINT; drag_modified.clear(); drag_painted_value = _get_painted_value(); - Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position()); + Vector2i coords = p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position(), true); coords = p_tile_set_atlas_source->get_tile_at_coords(coords); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { TileMapCell cell; @@ -1015,8 +1015,8 @@ void TileDataDefaultEditor::forward_painting_atlas_gui_input(TileAtlasView *p_ti } else { if (drag_type == DRAG_TYPE_PAINT_RECT) { Rect2i rect; - rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); - rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position())); + rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos, true)); + rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position(), true)); rect = rect.abs(); drag_modified.clear(); @@ -1812,8 +1812,8 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas p_canvas_item->draw_set_transform_matrix(p_transform); Rect2i rect; - rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); - rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(p_transform.affine_inverse().xform(p_canvas_item->get_local_mouse_position()))); + rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos, true)); + rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(p_transform.affine_inverse().xform(p_canvas_item->get_local_mouse_position()), true)); rect = rect.abs(); RBSet edited; @@ -1842,8 +1842,8 @@ void TileDataTerrainsEditor::forward_draw_over_atlas(TileAtlasView *p_tile_atlas int terrain_set = int(painted["terrain_set"]); Rect2i rect; - rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); - rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(p_transform.affine_inverse().xform(p_canvas_item->get_local_mouse_position()))); + rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos, true)); + rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(p_transform.affine_inverse().xform(p_canvas_item->get_local_mouse_position()), true)); rect = rect.abs(); RBSet edited; @@ -2003,7 +2003,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t Ref mm = p_event; if (mm.is_valid()) { if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET) { - Vector line = Geometry2D::bresenham_line(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_pos), p_tile_atlas_view->get_atlas_tile_coords_at_pos(mm->get_position())); + Vector line = Geometry2D::bresenham_line(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_pos, true), p_tile_atlas_view->get_atlas_tile_coords_at_pos(mm->get_position(), true)); for (int i = 0; i < line.size(); i++) { Vector2i coords = p_tile_set_atlas_source->get_tile_at_coords(line[i]); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { @@ -2037,7 +2037,7 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t } else if (drag_type == DRAG_TYPE_PAINT_TERRAIN_BITS) { int terrain_set = Dictionary(drag_painted_value)["terrain_set"]; int terrain = Dictionary(drag_painted_value)["terrain"]; - Vector line = Geometry2D::bresenham_line(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_pos), p_tile_atlas_view->get_atlas_tile_coords_at_pos(mm->get_position())); + Vector line = Geometry2D::bresenham_line(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_pos, true), p_tile_atlas_view->get_atlas_tile_coords_at_pos(mm->get_position(), true)); for (int i = 0; i < line.size(); i++) { Vector2i coords = p_tile_set_atlas_source->get_tile_at_coords(line[i]); if (coords != TileSetSource::INVALID_ATLAS_COORDS) { @@ -2238,8 +2238,8 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t EditorUndoRedoManager *undo_redo = EditorUndoRedoManager::get_singleton(); if (drag_type == DRAG_TYPE_PAINT_TERRAIN_SET_RECT) { Rect2i rect; - rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); - rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position())); + rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos, true)); + rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position(), true)); rect = rect.abs(); RBSet edited; @@ -2326,8 +2326,8 @@ void TileDataTerrainsEditor::forward_painting_atlas_gui_input(TileAtlasView *p_t int terrain = int(painted["terrain"]); Rect2i rect; - rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos)); - rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position())); + rect.set_position(p_tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_pos, true)); + rect.set_end(p_tile_atlas_view->get_atlas_tile_coords_at_pos(mb->get_position(), true)); rect = rect.abs(); RBSet edited; diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp index 81dd8bc8a6..23b6da438c 100644 --- a/editor/plugins/tiles/tile_map_editor.cpp +++ b/editor/plugins/tiles/tile_map_editor.cpp @@ -1716,8 +1716,8 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_draw() { // Draw the selection rect. if (tile_set_dragging_selection) { - Vector2i start_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos); - Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos, true); + Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Rect2i region = Rect2i(start_tile, end_tile - start_tile).abs(); region.size += Vector2i(1, 1); @@ -1812,8 +1812,8 @@ void TileMapEditorTilesPlugin::_tile_atlas_control_gui_input(const Refget_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos); - Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_set_drag_start_mouse_pos, true); + Vector2i end_tile = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); if (start_tile != TileSetSource::INVALID_ATLAS_COORDS && end_tile != TileSetSource::INVALID_ATLAS_COORDS) { Rect2i region = Rect2i(start_tile, end_tile - start_tile).abs(); region.size += Vector2i(1, 1); diff --git a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp index 43eaafc02c..9e2cb47c23 100644 --- a/editor/plugins/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/plugins/tiles/tile_set_atlas_source_editor.cpp @@ -1015,9 +1015,9 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Ref mm = p_event; if (mm.is_valid()) { - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i last_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i last_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_last_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Vector2i grid_size = tile_set_atlas_source->get_atlas_grid_size(); @@ -1066,7 +1066,6 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_gui_input(const Refget_tile_size_in_atlas(drag_current_tile)) / 2.0 - Vector2(0.5, 0.5)) * tile_set->get_tile_size(); Vector2i coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position() - mouse_offset); - coords = coords.max(Vector2i(0, 0)).min(grid_size - Vector2i(1, 1)); if (drag_current_tile != coords && tile_set_atlas_source->has_room_for_tile(coords, tile_set_atlas_source->get_tile_size_in_atlas(drag_current_tile), tile_set_atlas_source->get_tile_animation_columns(drag_current_tile), tile_set_atlas_source->get_tile_animation_separation(drag_current_tile), tile_set_atlas_source->get_tile_animation_frames_count(drag_current_tile), drag_current_tile)) { tile_set_atlas_source->move_tile_in_atlas(drag_current_tile, coords); selection.clear(); @@ -1334,8 +1333,8 @@ void TileSetAtlasSourceEditor::_end_dragging() { undo_redo->commit_action(); } break; case DRAG_TYPE_CREATE_TILES_USING_RECT: { - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Rect2i area = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs(); area.set_end((area.get_end() + Vector2i(1, 1)).min(tile_set_atlas_source->get_atlas_grid_size())); undo_redo->create_action(TTR("Create tiles")); @@ -1351,8 +1350,8 @@ void TileSetAtlasSourceEditor::_end_dragging() { undo_redo->commit_action(); } break; case DRAG_TYPE_REMOVE_TILES_USING_RECT: { - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Rect2i area = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs(); area.set_end((area.get_end() + Vector2i(1, 1)).min(tile_set_atlas_source->get_atlas_grid_size())); List list; @@ -1402,8 +1401,8 @@ void TileSetAtlasSourceEditor::_end_dragging() { } break; case DRAG_TYPE_RECT_SELECT: { - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); ERR_FAIL_COND(start_base_tiles_coords == TileSetSource::INVALID_ATLAS_COORDS); ERR_FAIL_COND(new_base_tiles_coords == TileSetSource::INVALID_ATLAS_COORDS); @@ -1771,8 +1770,8 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { } } else if (drag_type == DRAG_TYPE_RECT_SELECT || drag_type == DRAG_TYPE_REMOVE_TILES_USING_RECT) { // Draw tiles to be removed. - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Rect2i area = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs(); area.set_end((area.get_end() + Vector2i(1, 1)).min(tile_set_atlas_source->get_atlas_grid_size())); @@ -1801,8 +1800,8 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { Vector2i separation = tile_set_atlas_source->get_separation(); Vector2i tile_size = tile_set_atlas_source->get_texture_region_size(); - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Rect2i area = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs(); area.set_end((area.get_end() + Vector2i(1, 1)).min(tile_set_atlas_source->get_atlas_grid_size())); for (int x = area.get_position().x; x < area.get_end().x; x++) { @@ -1819,8 +1818,8 @@ void TileSetAtlasSourceEditor::_tile_atlas_control_draw() { // Draw the hovered tile. if (drag_type == DRAG_TYPE_REMOVE_TILES_USING_RECT || drag_type == DRAG_TYPE_CREATE_TILES_USING_RECT) { // Draw the rect. - Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos); - Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position()); + Vector2i start_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(drag_start_mouse_pos, true); + Vector2i new_base_tiles_coords = tile_atlas_view->get_atlas_tile_coords_at_pos(tile_atlas_control->get_local_mouse_position(), true); Rect2i area = Rect2i(start_base_tiles_coords, new_base_tiles_coords - start_base_tiles_coords).abs(); area.set_end((area.get_end() + Vector2i(1, 1)).min(tile_set_atlas_source->get_atlas_grid_size())); Vector2i margins = tile_set_atlas_source->get_margins(); -- cgit v1.2.3