Make tilemap lines/rectangles their own tools
This commit is contained in:
parent
277d2f1f50
commit
8e2608b2d6
2 changed files with 178 additions and 44 deletions
|
@ -64,6 +64,8 @@ void TileMapEditor::_notification(int p_what) {
|
|||
}
|
||||
|
||||
paint_button->set_icon(get_theme_icon("Edit", "EditorIcons"));
|
||||
line_button->set_icon(get_theme_icon("CurveLinear", "EditorIcons"));
|
||||
rectangle_button->set_icon(get_theme_icon("RectangleShape2D", "EditorIcons"));
|
||||
bucket_fill_button->set_icon(get_theme_icon("Bucket", "EditorIcons"));
|
||||
picker_button->set_icon(get_theme_icon("ColorPick", "EditorIcons"));
|
||||
select_button->set_icon(get_theme_icon("ActionCopy", "EditorIcons"));
|
||||
|
@ -91,9 +93,10 @@ void TileMapEditor::_notification(int p_what) {
|
|||
}
|
||||
|
||||
void TileMapEditor::_update_button_tool() {
|
||||
Button *tb[4] = { paint_button, bucket_fill_button, picker_button, select_button };
|
||||
Button *tb[6] = { paint_button, line_button, rectangle_button, bucket_fill_button, picker_button, select_button };
|
||||
|
||||
// Unpress all buttons
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
tb[i]->set_pressed(false);
|
||||
}
|
||||
|
||||
|
@ -103,6 +106,12 @@ void TileMapEditor::_update_button_tool() {
|
|||
case TOOL_PAINTING: {
|
||||
paint_button->set_pressed(true);
|
||||
} break;
|
||||
case TOOL_LINE_PAINT: {
|
||||
line_button->set_pressed(true);
|
||||
} break;
|
||||
case TOOL_RECTANGLE_PAINT: {
|
||||
rectangle_button->set_pressed(true);
|
||||
} break;
|
||||
case TOOL_BUCKET: {
|
||||
bucket_fill_button->set_pressed(true);
|
||||
} break;
|
||||
|
@ -993,19 +1002,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
|
||||
if (tool == TOOL_NONE) {
|
||||
if (mb->get_shift()) {
|
||||
if (mb->get_command()) {
|
||||
tool = TOOL_RECTANGLE_PAINT;
|
||||
} else {
|
||||
tool = TOOL_LINE_PAINT;
|
||||
}
|
||||
|
||||
selection_active = false;
|
||||
rectangle_begin = over_tile;
|
||||
|
||||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
tool = TOOL_PAINTING;
|
||||
_update_button_tool();
|
||||
|
||||
if (mb->get_command()) {
|
||||
tool = TOOL_PICKING;
|
||||
|
@ -1014,12 +1012,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
tool = TOOL_PAINTING;
|
||||
_update_button_tool();
|
||||
}
|
||||
|
||||
if (tool == TOOL_PAINTING) {
|
||||
if (tool == TOOL_LINE_PAINT || tool == TOOL_RECTANGLE_PAINT) {
|
||||
selection_active = false;
|
||||
rectangle_begin = over_tile;
|
||||
|
||||
mouse_down = true;
|
||||
} else if (tool == TOOL_PAINTING) {
|
||||
Vector<int> ids = get_selected_tiles();
|
||||
|
||||
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
|
||||
|
@ -1050,6 +1050,10 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
paint_undo.clear();
|
||||
}
|
||||
} else if (tool == TOOL_LINE_PAINT) {
|
||||
if (!mouse_down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector<int> ids = get_selected_tiles();
|
||||
|
||||
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
|
||||
|
@ -1062,8 +1066,17 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
paint_undo.clear();
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
mouse_down = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mouse_down = false;
|
||||
} else if (tool == TOOL_RECTANGLE_PAINT) {
|
||||
if (!mouse_down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Vector<int> ids = get_selected_tiles();
|
||||
|
||||
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
|
||||
|
@ -1076,7 +1089,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
_finish_undo();
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
mouse_down = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mouse_down = false;
|
||||
} else if (tool == TOOL_PASTING) {
|
||||
Point2 ofs = over_tile - rectangle.position;
|
||||
Vector<int> ids;
|
||||
|
@ -1141,6 +1159,28 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
|
||||
if (tool == TOOL_PASTING) {
|
||||
tool = TOOL_NONE;
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tool == TOOL_LINE_PAINT) {
|
||||
tool = TOOL_LINE_ERASE;
|
||||
mouse_down = true;
|
||||
rectangle_begin = over_tile;
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tool == TOOL_RECTANGLE_PAINT) {
|
||||
tool = TOOL_RECTANGLE_ERASE;
|
||||
mouse_down = true;
|
||||
rectangle_begin = over_tile;
|
||||
copydata.clear();
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
@ -1155,39 +1195,74 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
Point2 local = node->world_to_map(xform_inv.xform(mb->get_position()));
|
||||
|
||||
_start_undo(TTR("Erase TileMap"));
|
||||
|
||||
if (mb->get_shift()) {
|
||||
if (mb->get_command()) {
|
||||
tool = TOOL_RECTANGLE_ERASE;
|
||||
} else {
|
||||
tool = TOOL_LINE_ERASE;
|
||||
}
|
||||
|
||||
selection_active = false;
|
||||
rectangle_begin = local;
|
||||
} else {
|
||||
tool = TOOL_ERASING;
|
||||
|
||||
_set_cell(local, invalid_cell);
|
||||
}
|
||||
tool = TOOL_ERASING;
|
||||
_set_cell(local, invalid_cell);
|
||||
|
||||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
|
||||
} else {
|
||||
if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
|
||||
_finish_undo();
|
||||
|
||||
if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
if (tool == TOOL_LINE_ERASE) {
|
||||
if (!mouse_down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
tool = TOOL_NONE;
|
||||
|
||||
tool = TOOL_LINE_PAINT;
|
||||
_update_button_tool();
|
||||
return true;
|
||||
|
||||
Vector<int> ids = get_selected_tiles();
|
||||
|
||||
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
|
||||
_start_undo(TTR("Line Erase"));
|
||||
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
|
||||
_set_cell(E->key(), invalid_cell, flip_h, flip_v, transpose);
|
||||
}
|
||||
_finish_undo();
|
||||
paint_undo.clear();
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
mouse_down = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mouse_down = false;
|
||||
} else if (tool == TOOL_RECTANGLE_ERASE) {
|
||||
if (!mouse_down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
tool = TOOL_RECTANGLE_PAINT;
|
||||
_update_button_tool();
|
||||
|
||||
Vector<int> ids = get_selected_tiles();
|
||||
|
||||
if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
|
||||
_start_undo(TTR("Rectangle Erase"));
|
||||
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
|
||||
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
|
||||
_set_cell(Point2i(j, i), invalid_cell, flip_h, flip_v, transpose);
|
||||
}
|
||||
}
|
||||
_finish_undo();
|
||||
paint_undo.clear();
|
||||
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
mouse_down = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
mouse_down = false;
|
||||
tool = TOOL_RECTANGLE_PAINT;
|
||||
}
|
||||
|
||||
if (tool == TOOL_ERASING) {
|
||||
tool = TOOL_NONE;
|
||||
_update_button_tool();
|
||||
|
||||
return true;
|
||||
} else if (tool == TOOL_BUCKET) {
|
||||
Vector<int> ids;
|
||||
ids.push_back(node->get_cell(over_tile.x, over_tile.y));
|
||||
|
@ -1278,6 +1353,10 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
Vector<int> tmp_cell;
|
||||
bool erasing = (tool == TOOL_LINE_ERASE);
|
||||
|
||||
if (!mouse_down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
tmp_cell.push_back(0);
|
||||
if (erasing && paint_undo.size()) {
|
||||
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
|
||||
|
@ -1308,7 +1387,20 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
Vector<int> tmp_cell;
|
||||
tmp_cell.push_back(0);
|
||||
|
||||
_select(rectangle_begin, over_tile);
|
||||
Point2i end_tile = over_tile;
|
||||
|
||||
if (!mouse_down) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mm->get_shift()) {
|
||||
int size = fmax(ABS(end_tile.x - rectangle_begin.x), ABS(end_tile.y - rectangle_begin.y));
|
||||
int xDirection = MAX(MIN(end_tile.x - rectangle_begin.x, 1), -1);
|
||||
int yDirection = MAX(MIN(end_tile.y - rectangle_begin.y, 1), -1);
|
||||
end_tile = rectangle_begin + Point2i(xDirection * size, yDirection * size);
|
||||
}
|
||||
|
||||
_select(rectangle_begin, end_tile);
|
||||
|
||||
if (tool == TOOL_RECTANGLE_ERASE) {
|
||||
if (paint_undo.size()) {
|
||||
|
@ -1379,6 +1471,20 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
|
|||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
if (ED_IS_SHORTCUT("tile_map_editor/line_fill", p_event)) {
|
||||
tool = TOOL_LINE_PAINT;
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
if (ED_IS_SHORTCUT("tile_map_editor/rectangle_fill", p_event)) {
|
||||
tool = TOOL_RECTANGLE_PAINT;
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
||||
_update_button_tool();
|
||||
return true;
|
||||
}
|
||||
if (ED_IS_SHORTCUT("tile_map_editor/bucket_fill", p_event)) {
|
||||
tool = TOOL_BUCKET;
|
||||
CanvasItemEditor::get_singleton()->update_viewport();
|
||||
|
@ -1637,6 +1743,10 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
}
|
||||
|
||||
if (tool == TOOL_LINE_PAINT) {
|
||||
if (!mouse_down) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (paint_undo.empty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -1652,6 +1762,10 @@ void TileMapEditor::forward_canvas_draw_over_viewport(Control *p_overlay) {
|
|||
}
|
||||
|
||||
} else if (tool == TOOL_RECTANGLE_PAINT) {
|
||||
if (!mouse_down) {
|
||||
return;
|
||||
}
|
||||
|
||||
Vector<int> ids = get_selected_tiles();
|
||||
|
||||
if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL) {
|
||||
|
@ -1865,6 +1979,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
|||
tool = TOOL_NONE;
|
||||
selection_active = false;
|
||||
mouse_over = false;
|
||||
mouse_down = false;
|
||||
|
||||
flip_h = false;
|
||||
flip_v = false;
|
||||
|
@ -1962,11 +2077,27 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
|||
paint_button = memnew(Button);
|
||||
paint_button->set_flat(true);
|
||||
paint_button->set_shortcut(ED_SHORTCUT("tile_map_editor/paint_tile", TTR("Paint Tile"), KEY_P));
|
||||
paint_button->set_tooltip(TTR("Shift+LMB: Line Draw\nShift+Ctrl+LMB: Rectangle Paint"));
|
||||
paint_button->set_tooltip(TTR("RMB: Erase"));
|
||||
paint_button->connect("pressed", callable_mp(this, &TileMapEditor::_button_tool_select), make_binds(TOOL_NONE));
|
||||
paint_button->set_toggle_mode(true);
|
||||
toolbar->add_child(paint_button);
|
||||
|
||||
line_button = memnew(Button);
|
||||
line_button->set_flat(true);
|
||||
line_button->set_shortcut(ED_SHORTCUT("tile_map_editor/line_fill", TTR("Line Fill"), KEY_L));
|
||||
line_button->set_tooltip(TTR("RMB: Erase"));
|
||||
line_button->connect("pressed", callable_mp(this, &TileMapEditor::_button_tool_select), make_binds(TOOL_LINE_PAINT));
|
||||
line_button->set_toggle_mode(true);
|
||||
toolbar->add_child(line_button);
|
||||
|
||||
rectangle_button = memnew(Button);
|
||||
rectangle_button->set_flat(true);
|
||||
rectangle_button->set_shortcut(ED_SHORTCUT("tile_map_editor/rectangle_fill", TTR("Rectangle Fill"), KEY_O));
|
||||
rectangle_button->set_tooltip(TTR("Shift+LMB: Keep 1:1 proporsions\nRMB: Erase"));
|
||||
rectangle_button->connect("pressed", callable_mp(this, &TileMapEditor::_button_tool_select), make_binds(TOOL_RECTANGLE_PAINT));
|
||||
rectangle_button->set_toggle_mode(true);
|
||||
toolbar->add_child(rectangle_button);
|
||||
|
||||
bucket_fill_button = memnew(Button);
|
||||
bucket_fill_button->set_flat(true);
|
||||
bucket_fill_button->set_shortcut(ED_SHORTCUT("tile_map_editor/bucket_fill", TTR("Bucket Fill"), KEY_B));
|
||||
|
|
|
@ -88,6 +88,8 @@ class TileMapEditor : public VBoxContainer {
|
|||
MenuButton *options;
|
||||
|
||||
Button *paint_button;
|
||||
Button *line_button;
|
||||
Button *rectangle_button;
|
||||
Button *bucket_fill_button;
|
||||
Button *picker_button;
|
||||
Button *select_button;
|
||||
|
@ -106,6 +108,7 @@ class TileMapEditor : public VBoxContainer {
|
|||
|
||||
bool selection_active;
|
||||
bool mouse_over;
|
||||
bool mouse_down;
|
||||
|
||||
bool flip_h;
|
||||
bool flip_v;
|
||||
|
|
Loading…
Reference in a new issue