From fd06683cb4cf16fd607c28114fcbc659657929b5 Mon Sep 17 00:00:00 2001 From: Franklin Sobrinho Date: Fri, 11 Mar 2016 14:06:54 -0300 Subject: Tilemap Editor: Line drawing and erasing --- tools/editor/plugins/tile_map_editor_plugin.cpp | 140 ++++++++++++++++++++++-- tools/editor/plugins/tile_map_editor_plugin.h | 2 + 2 files changed, 133 insertions(+), 9 deletions(-) diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index a765bc6fe2..0a2925fbd4 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -387,6 +387,52 @@ void TileMapEditor::_update_copydata() { } } +static inline Vector line(int x0, int x1, int y0, int y1) { + + Vector points; + + float dx = ABS(x1 - x0); + float dy = ABS(y1 - y0); + + int x = x0; + int y = y0; + + int sx = x0 > x1 ? -1 : 1; + int sy = y0 > y1 ? -1 : 1; + + if (dx > dy) { + float err = dx/2; + + while (x != x1) { + points.push_back(Vector2(x, y)); + + err -= dy; + if (err < 0) { + y += sy; + err += dx; + } + x += sx; + } + } else { + float err = dy/2; + + while (y != y1) { + points.push_back(Vector2(x, y)); + + err -= dx; + if (err < 0) { + x += sx; + err += dy; + } + y += sy; + } + } + + points.push_back(Vector2(x, y)); + + return points; +} + bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (!node || !node->get_tileset().is_valid() || !node->is_visible()) @@ -409,7 +455,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { return false; //drag if (tool==TOOL_NONE) { - if (mb.mod.shift) { + if (mb.mod.shift && mb.mod.control) { tool=TOOL_RECTANGLE_PAINT; selection_active=false; @@ -417,6 +463,14 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { return true; } + if (mb.mod.shift) { + + tool=TOOL_LINE_PAINT; + selection_active=false; + rectangle_begin=node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); + + return true; + } if (mb.mod.control) { tool=TOOL_PICKING; @@ -494,10 +548,24 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { undo_redo->add_do_method(node,"set_cellv",Point2(p),id,node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y)); undo_redo->add_undo_method(node,"set_cellv",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr); } - undo_redo->commit_action(); paint_undo.clear(); } + } else if (tool==TOOL_LINE_PAINT) { + + int id=get_selected_tile(); + + if (id!=TileMap::INVALID_CELL) { + + undo_redo->create_action("Line Draw"); + for(Map::Element *E=paint_undo.front();E;E=E->next()) { + + _set_cell(E->key(), id, flip_h, flip_v, transpose, true); + } + undo_redo->commit_action(); + + canvas_item_editor->update(); + } } else if (tool==TOOL_RECTANGLE_PAINT) { int id=get_selected_tile(); @@ -551,7 +619,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (tool==TOOL_NONE) { - if (mb.mod.shift) { + if (mb.mod.shift && mb.mod.control) { tool=TOOL_RECTANGLE_ERASE; @@ -559,6 +627,14 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { rectangle_begin=node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); paint_undo.clear(); + } else if (mb.mod.shift) { + + tool=TOOL_LINE_ERASE; + + selection_active=false; + rectangle_begin=node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); + paint_undo.clear(); + } else { tool=TOOL_ERASING; @@ -573,7 +649,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } } else { - if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE) { + if (tool==TOOL_ERASING || tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { if (paint_undo.size()) { undo_redo->create_action("Erase TileMap"); @@ -588,7 +664,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { paint_undo.clear(); } - if (tool==TOOL_RECTANGLE_ERASE) { + if (tool==TOOL_RECTANGLE_ERASE || tool==TOOL_LINE_ERASE) { canvas_item_editor->update(); } tool=TOOL_NONE; @@ -630,6 +706,38 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { return true; } + if (tool==TOOL_LINE_PAINT || tool==TOOL_LINE_ERASE) { + + int id = get_selected_tile(); + + bool erasing = (tool==TOOL_LINE_ERASE); + + if (id!=TileMap::INVALID_CELL) { + + if (erasing && paint_undo.size()) { + + for (Map::Element *E=paint_undo.front();E;E=E->next()) { + + _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr); + } + } + + paint_undo.clear(); + + Vector points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y); + for (int i=0;iupdate(); + } + + return true; + } if (tool==TOOL_RECTANGLE_PAINT || tool==TOOL_RECTANGLE_ERASE) { _select(rectangle_begin, over_tile); @@ -755,6 +863,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { return false; } + void TileMapEditor::_canvas_draw() { if (!node) @@ -867,7 +976,6 @@ void TileMapEditor::_canvas_draw() { canvas_item_editor->draw_colored_polygon(points, Color(0.2,0.8,1,0.4)); } - if (mouse_over){ Vector2 endpoints[4]={ @@ -898,6 +1006,23 @@ void TileMapEditor::_canvas_draw() { return; + } + + if (tool==TOOL_LINE_PAINT) { + + if (paint_undo.empty()) + return; + + int id = get_selected_tile(); + + if (id==TileMap::INVALID_CELL) + return; + + for (Map::Element *E=paint_undo.front();E;E=E->next()) { + + _draw_cell(id, E->key(), flip_h, flip_v, transpose, xform); + } + } else if (tool==TOOL_RECTANGLE_PAINT) { int id = get_selected_tile(); @@ -954,11 +1079,8 @@ void TileMapEditor::_canvas_draw() { _draw_cell(st, over_tile, flip_h, flip_v, transpose, xform); } } - } - - void TileMapEditor::edit(Node *p_tile_map) { search_box->set_text(""); diff --git a/tools/editor/plugins/tile_map_editor_plugin.h b/tools/editor/plugins/tile_map_editor_plugin.h index b95f267de3..70cd47404f 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.h +++ b/tools/editor/plugins/tile_map_editor_plugin.h @@ -52,6 +52,8 @@ class TileMapEditor : public VBoxContainer { TOOL_ERASING, TOOL_RECTANGLE_PAINT, TOOL_RECTANGLE_ERASE, + TOOL_LINE_PAINT, + TOOL_LINE_ERASE, TOOL_SELECTING, TOOL_DUPLICATING, TOOL_PICKING -- cgit v1.2.3