summaryrefslogtreecommitdiff
path: root/editor/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'editor/plugins')
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp3
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp9
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp22
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp1
-rw-r--r--editor/plugins/root_motion_editor_plugin.cpp3
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp31
-rw-r--r--editor/plugins/script_text_editor.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp178
-rw-r--r--editor/plugins/tile_map_editor_plugin.h7
10 files changed, 161 insertions, 97 deletions
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 7d0e2929bd..3efb2736b5 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -767,7 +767,8 @@ AnimationNodeBlendTreeEditor::AnimationNodeBlendTreeEditor() {
add_options.push_back(AddOption("Animation", "AnimationNodeAnimation"));
add_options.push_back(AddOption("OneShot", "AnimationNodeOneShot"));
- add_options.push_back(AddOption("Add", "AnimationNodeAdd"));
+ add_options.push_back(AddOption("Add2", "AnimationNodeAdd2"));
+ add_options.push_back(AddOption("Add3", "AnimationNodeAdd3"));
add_options.push_back(AddOption("Blend2", "AnimationNodeBlend2"));
add_options.push_back(AddOption("Blend3", "AnimationNodeBlend3"));
add_options.push_back(AddOption("Seek", "AnimationNodeTimeSeek"));
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 3477a6ec30..b38ff239cc 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -144,6 +144,7 @@ void AnimationPlayerEditor::_notification(int p_what) {
ITEM_ICON(TOOL_DUPLICATE_ANIM, "Duplicate");
ITEM_ICON(TOOL_RENAME_ANIM, "Rename");
ITEM_ICON(TOOL_EDIT_TRANSITIONS, "Blend");
+ ITEM_ICON(TOOL_EDIT_RESOURCE, "Edit");
ITEM_ICON(TOOL_REMOVE_ANIM, "Remove");
//ITEM_ICON(TOOL_COPY_ANIM, "Copy");
//ITEM_ICON(TOOL_PASTE_ANIM, "Paste");
@@ -1102,9 +1103,12 @@ void AnimationPlayerEditor::_animation_about_to_show_menu() {
void AnimationPlayerEditor::_animation_tool_menu(int p_option) {
- String current = animation->get_item_text(animation->get_selected());
+ String current;
+ if (animation->get_selected() >= 0 && animation->get_selected() < animation->get_item_count())
+ current = animation->get_item_text(animation->get_selected());
+
Ref<Animation> anim;
- if (current != "") {
+ if (current != String()) {
anim = player->get_animation(current);
}
@@ -1667,6 +1671,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
tool_anim->get_popup()->add_separator();
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/rename_animation", TTR("Rename...")), TOOL_RENAME_ANIM);
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/edit_transitions", TTR("Edit Transitions...")), TOOL_EDIT_TRANSITIONS);
+ tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/open_animation_in_inspector", TTR("Open in Inspector")), TOOL_EDIT_RESOURCE);
tool_anim->get_popup()->add_separator();
tool_anim->get_popup()->add_shortcut(ED_SHORTCUT("animation_player_editor/remove_animation", TTR("Remove")), TOOL_REMOVE_ANIM);
hb->add_child(tool_anim);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 0f46f7f004..48ee011fc1 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -543,7 +543,6 @@ void CanvasItemEditor::_get_bones_at_pos(const Point2 &p_pos, Vector<_SelectResu
for (Map<BoneKey, BoneList>::Element *E = bone_list.front(); E; E = E->next()) {
Node2D *from_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().from));
- Node2D *to_node = Object::cast_to<Node2D>(ObjectDB::get_instance(E->key().to));
Vector<Vector2> bone_shape;
if (!_get_bone_shape(&bone_shape, NULL, E))
@@ -719,16 +718,17 @@ Vector2 CanvasItemEditor::_anchor_to_position(const Control *p_control, Vector2
ERR_FAIL_COND_V(!p_control, Vector2());
Transform2D parent_transform = p_control->get_transform().affine_inverse();
- Size2 parent_size = p_control->get_parent_area_size();
+ Rect2 parent_rect = p_control->get_parent_anchorable_rect();
- return parent_transform.xform(Vector2(parent_size.x * anchor.x, parent_size.y * anchor.y));
+ return parent_transform.xform(parent_rect.position + Vector2(parent_rect.size.x * anchor.x, parent_rect.size.y * anchor.y));
}
Vector2 CanvasItemEditor::_position_to_anchor(const Control *p_control, Vector2 position) {
ERR_FAIL_COND_V(!p_control, Vector2());
- Size2 parent_size = p_control->get_parent_area_size();
- return p_control->get_transform().xform(position) / parent_size;
+ Rect2 parent_rect = p_control->get_parent_anchorable_rect();
+
+ return (p_control->get_transform().xform(position) - parent_rect.position) / parent_rect.size;
}
void CanvasItemEditor::_save_canvas_item_state(List<CanvasItem *> p_canvas_items, bool save_bones) {
@@ -2491,10 +2491,12 @@ void CanvasItemEditor::_draw_selection() {
Transform2D parent_transform = xform * control->get_transform().affine_inverse();
float node_pos_in_parent[4];
- node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * control->get_parent_area_size().width + control->get_margin(MARGIN_LEFT);
- node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * control->get_parent_area_size().height + control->get_margin(MARGIN_TOP);
- node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * control->get_parent_area_size().width + control->get_margin(MARGIN_RIGHT);
- node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * control->get_parent_area_size().height + control->get_margin(MARGIN_BOTTOM);
+ Rect2 parent_rect = control->get_parent_anchorable_rect();
+
+ node_pos_in_parent[0] = control->get_anchor(MARGIN_LEFT) * parent_rect.size.width + control->get_margin(MARGIN_LEFT) + parent_rect.position.x;
+ node_pos_in_parent[1] = control->get_anchor(MARGIN_TOP) * parent_rect.size.height + control->get_margin(MARGIN_TOP) + parent_rect.position.y;
+ node_pos_in_parent[2] = control->get_anchor(MARGIN_RIGHT) * parent_rect.size.width + control->get_margin(MARGIN_RIGHT) + parent_rect.position.x;
+ node_pos_in_parent[3] = control->get_anchor(MARGIN_BOTTOM) * parent_rect.size.height + control->get_margin(MARGIN_BOTTOM) + parent_rect.position.y;
Point2 start, end;
switch (drag_type) {
@@ -4351,7 +4353,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
snap_button->set_toggle_mode(true);
snap_button->connect("toggled", this, "_button_toggle_snap");
snap_button->set_tooltip(TTR("Toggle snapping."));
- snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_S));
+ snap_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/use_snap", TTR("Use Snap"), KEY_MASK_SHIFT | KEY_S));
snap_config_menu = memnew(MenuButton);
hb->add_child(snap_config_menu);
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index ed41e1931e..4840b1899d 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -563,6 +563,7 @@ void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
if (uv_move_current == UV_MODE_REMOVE_SPLIT) {
+ splits_prev = node->get_splits();
for (int i = 0; i < splits_prev.size(); i += 2) {
if (splits_prev[i] < 0 || splits_prev[i] >= points_prev.size())
continue;
diff --git a/editor/plugins/root_motion_editor_plugin.cpp b/editor/plugins/root_motion_editor_plugin.cpp
index e316116b43..89c1b3a978 100644
--- a/editor/plugins/root_motion_editor_plugin.cpp
+++ b/editor/plugins/root_motion_editor_plugin.cpp
@@ -124,9 +124,10 @@ void EditorPropertyRootMotion::_node_assign() {
ti = filters->create_item(ti);
parenthood[accum] = ti;
ti->set_text(0, F->get());
- ti->set_selectable(0, false);
+ ti->set_selectable(0, true);
ti->set_editable(0, false);
ti->set_icon(0, get_icon("BoneAttachment", "EditorIcons"));
+ ti->set_metadata(0, accum);
} else {
ti = parenthood[accum];
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 9724017787..aa4673f41e 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2884,7 +2884,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
error_dialog = memnew(AcceptDialog);
add_child(error_dialog);
- error_dialog->get_ok()->set_text(TTR("I see.."));
+ error_dialog->get_ok()->set_text(TTR("I see..."));
debugger = memnew(ScriptEditorDebugger(editor));
debugger->connect("goto_script_line", this, "_goto_script_line");
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index aef2a53dd1..345c7c06eb 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1289,16 +1289,26 @@ void ScriptTextEditor::_edit_option(int p_op) {
void ScriptTextEditor::add_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
highlighters[p_highlighter->get_name()] = p_highlighter;
- highlighter_menu->get_popup()->add_item(p_highlighter->get_name());
+ highlighter_menu->add_radio_check_item(p_highlighter->get_name());
}
void ScriptTextEditor::set_syntax_highlighter(SyntaxHighlighter *p_highlighter) {
TextEdit *te = code_editor->get_text_edit();
te->_set_syntax_highlighting(p_highlighter);
+ if (p_highlighter != NULL)
+ highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(p_highlighter->get_name()), true);
+ else
+ highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text("Standard"), true);
}
void ScriptTextEditor::_change_syntax_highlighter(int p_idx) {
- set_syntax_highlighter(highlighters[highlighter_menu->get_popup()->get_item_text(p_idx)]);
+ Map<String, SyntaxHighlighter *>::Element *el = highlighters.front();
+ while (el != NULL) {
+ highlighter_menu->set_item_checked(highlighter_menu->get_item_idx_from_text(el->key()), false);
+ el = el->next();
+ }
+ // highlighter_menu->set_item_checked(p_idx, true);
+ set_syntax_highlighter(highlighters[highlighter_menu->get_item_text(p_idx)]);
}
void ScriptTextEditor::_bind_methods() {
@@ -1666,6 +1676,7 @@ ScriptTextEditor::ScriptTextEditor() {
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT);
edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT);
edit_menu->get_popup()->add_separator();
+
PopupMenu *convert_case = memnew(PopupMenu);
convert_case->set_name("convert_case");
edit_menu->get_popup()->add_child(convert_case);
@@ -1675,6 +1686,14 @@ ScriptTextEditor::ScriptTextEditor() {
convert_case->add_shortcut(ED_SHORTCUT("script_text_editor/capitalize", TTR("Capitalize")), EDIT_CAPITALIZE);
convert_case->connect("id_pressed", this, "_edit_option");
+ highlighters["Standard"] = NULL;
+ highlighter_menu = memnew(PopupMenu);
+ highlighter_menu->set_name("highlighter_menu");
+ edit_menu->get_popup()->add_child(highlighter_menu);
+ edit_menu->get_popup()->add_submenu_item(TTR("Syntax Highlighter"), "highlighter_menu");
+ highlighter_menu->add_radio_check_item(TTR("Standard"));
+ highlighter_menu->connect("id_pressed", this, "_change_syntax_highlighter");
+
search_menu = memnew(MenuButton);
edit_hb->add_child(search_menu);
search_menu->set_text(TTR("Search"));
@@ -1694,14 +1713,6 @@ ScriptTextEditor::ScriptTextEditor() {
edit_hb->add_child(edit_menu);
- highlighters["Standard"] = NULL;
-
- highlighter_menu = memnew(MenuButton);
- highlighter_menu->set_text(TTR("Syntax Highlighter"));
- highlighter_menu->get_popup()->add_item("Standard");
- highlighter_menu->get_popup()->connect("id_pressed", this, "_change_syntax_highlighter");
- edit_hb->add_child(highlighter_menu);
-
quick_open = memnew(ScriptEditorQuickOpen);
add_child(quick_open);
quick_open->connect("goto_line", this, "_goto_line");
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index a93e1a6fa8..a415f478e8 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -49,8 +49,8 @@ class ScriptTextEditor : public ScriptEditorBase {
HBoxContainer *edit_hb;
MenuButton *edit_menu;
- MenuButton *highlighter_menu;
MenuButton *search_menu;
+ PopupMenu *highlighter_menu;
PopupMenu *context_menu;
GotoLineDialog *goto_line_dialog;
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 7264af3488..19646f37b5 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -137,7 +137,7 @@ void TileMapEditor::_menu_option(int p_option) {
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), TileMap::INVALID_CELL, false, false, false);
+ _set_cell(Point2i(j, i), invalid_cell, false, false, false);
}
}
_finish_undo();
@@ -186,24 +186,34 @@ void TileMapEditor::_canvas_mouse_exit() {
canvas_item_editor->update();
}
-int TileMapEditor::get_selected_tile() const {
+Vector<int> TileMapEditor::get_selected_tiles() const {
- int item = palette->get_current();
+ Vector<int> items = palette->get_selected_items();
- if (item == -1)
- return TileMap::INVALID_CELL;
+ if (items.size() == 0) {
+ items.push_back(TileMap::INVALID_CELL);
+ return items;
+ }
- return palette->get_item_metadata(item);
+ for (int i = items.size() - 1; i >= 0; i--) {
+ items[i] = palette->get_item_metadata(items[i]);
+ }
+ return items;
}
-void TileMapEditor::set_selected_tile(int p_tile) {
+void TileMapEditor::set_selected_tiles(Vector<int> p_tiles) {
- int idx = palette->find_metadata(p_tile);
+ palette->unselect_all();
- if (idx >= 0) {
- palette->select(idx, true);
- palette->ensure_current_is_visible();
+ for (int i = p_tiles.size() - 1; i >= 0; i--) {
+ int idx = palette->find_metadata(p_tiles[i]);
+
+ if (idx >= 0) {
+ palette->select(idx, false);
+ }
}
+
+ palette->ensure_current_is_visible();
}
void TileMapEditor::_create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new) {
@@ -246,10 +256,14 @@ void TileMapEditor::_finish_undo() {
undo_redo->commit_action();
}
-void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose) {
+void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h, bool p_flip_v, bool p_transpose) {
ERR_FAIL_COND(!node);
+ if (p_values.size() == 0)
+ return;
+
+ int p_value = p_values[Math::rand() % p_values.size()];
int prev_val = node->get_cell(p_pos.x, p_pos.y);
bool prev_flip_h = node->is_cell_x_flipped(p_pos.x, p_pos.y);
@@ -339,7 +353,7 @@ void TileMapEditor::_update_palette() {
if (!node)
return;
- int selected = get_selected_tile();
+ Vector<int> selected = get_selected_tiles();
palette->clear();
manual_palette->clear();
manual_palette->hide();
@@ -428,14 +442,17 @@ void TileMapEditor::_update_palette() {
palette->set_item_metadata(palette->get_item_count() - 1, entries[i].id);
}
- if (selected != -1)
- set_selected_tile(selected);
- else
+ int sel_tile = selected.get(0);
+ if (selected.get(0) != TileMap::INVALID_CELL) {
+ set_selected_tiles(selected);
+ sel_tile = selected.get(Math::rand() % selected.size());
+ } else {
palette->select(0);
+ }
- if (manual_autotile && tileset->tile_get_tile_mode(get_selected_tile()) == TileSet::AUTO_TILE) {
+ if (manual_autotile && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) {
- const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(get_selected_tile());
+ const Map<Vector2, uint16_t> &tiles = tileset->autotile_get_bitmask_map(sel_tile);
Vector<Vector2> entries;
for (const Map<Vector2, uint16_t>::Element *E = tiles.front(); E; E = E->next()) {
@@ -443,7 +460,7 @@ void TileMapEditor::_update_palette() {
}
entries.sort();
- Ref<Texture> tex = tileset->tile_get_texture(get_selected_tile());
+ Ref<Texture> tex = tileset->tile_get_texture(sel_tile);
for (int i = 0; i < entries.size(); i++) {
@@ -451,9 +468,9 @@ void TileMapEditor::_update_palette() {
if (tex.is_valid()) {
- Rect2 region = tileset->tile_get_region(get_selected_tile());
- int spacing = tileset->autotile_get_spacing(get_selected_tile());
- region.size = tileset->autotile_get_size(get_selected_tile());
+ Rect2 region = tileset->tile_get_region(sel_tile);
+ int spacing = tileset->autotile_get_spacing(sel_tile);
+ region.size = tileset->autotile_get_size(sel_tile); // !!
region.position += (region.size + Vector2(spacing, spacing)) * entries[i];
if (!region.has_no_area())
@@ -488,7 +505,10 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) {
_update_palette();
}
- set_selected_tile(id);
+ Vector<int> selected;
+
+ selected.push_back(id);
+ set_selected_tiles(selected);
mirror_x->set_pressed(node->is_cell_x_flipped(p_pos.x, p_pos.y));
mirror_y->set_pressed(node->is_cell_y_flipped(p_pos.x, p_pos.y));
@@ -501,18 +521,21 @@ void TileMapEditor::_pick_tile(const Point2 &p_pos) {
PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool erase, bool preview) {
int prev_id = node->get_cell(p_start.x, p_start.y);
- int id = TileMap::INVALID_CELL;
+ Vector<int> ids;
+ ids.push_back(TileMap::INVALID_CELL);
if (!erase) {
- id = get_selected_tile();
+ ids = get_selected_tiles();
- if (id == TileMap::INVALID_CELL)
+ if (ids.size() == 0 && ids[0] == TileMap::INVALID_CELL)
return PoolVector<Vector2>();
} else if (prev_id == TileMap::INVALID_CELL) {
return PoolVector<Vector2>();
}
- if (id == prev_id) {
- return PoolVector<Vector2>();
+ for (int i = ids.size() - 1; i >= 0; i--) {
+ if (ids[i] == prev_id) {
+ return PoolVector<Vector2>();
+ }
}
Rect2i r = node->_edit_get_rect();
@@ -602,13 +625,13 @@ void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dicti
int len = p_points.size();
PoolVector<Vector2>::Read pr = p_points.read();
- int id = p_op["id"];
+ Vector<int> ids = p_op["id"];
bool xf = p_op["flip_h"];
bool yf = p_op["flip_v"];
bool tr = p_op["transpose"];
for (int i = 0; i < len; i++) {
- _set_cell(pr[i], id, xf, yf, tr);
+ _set_cell(pr[i], ids, xf, yf, tr);
node->make_bitmask_area_dirty(pr[i]);
}
node->update_dirty_bitmask();
@@ -621,7 +644,7 @@ void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) {
for (int i = 0; i < len; i++) {
- _set_cell(pr[i], TileMap::INVALID_CELL);
+ _set_cell(pr[i], invalid_cell);
}
}
@@ -885,9 +908,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (tool == TOOL_PAINTING) {
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
- if (id != TileMap::INVALID_CELL) {
+ if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
tool = TOOL_PAINTING;
@@ -910,25 +933,25 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (tool == TOOL_PAINTING) {
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
- if (id != TileMap::INVALID_CELL) {
+ if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
- _set_cell(over_tile, id, flip_h, flip_v, transpose);
+ _set_cell(over_tile, ids, flip_h, flip_v, transpose);
_finish_undo();
paint_undo.clear();
}
} else if (tool == TOOL_LINE_PAINT) {
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
- if (id != TileMap::INVALID_CELL) {
+ if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
_start_undo(TTR("Line Draw"));
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- _set_cell(E->key(), id, flip_h, flip_v, transpose);
+ _set_cell(E->key(), ids, flip_h, flip_v, transpose);
}
_finish_undo();
@@ -938,15 +961,15 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
- if (id != TileMap::INVALID_CELL) {
+ if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
_start_undo(TTR("Rectangle Paint"));
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), id, flip_h, flip_v, transpose);
+ _set_cell(Point2i(j, i), ids, flip_h, flip_v, transpose);
}
}
_finish_undo();
@@ -956,11 +979,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else if (tool == TOOL_DUPLICATING) {
Point2 ofs = over_tile - rectangle.position;
+ Vector<int> ids;
_start_undo(TTR("Duplicate"));
+ ids.push_back(0);
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose);
+ ids[0] = E->get().cell;
+ _set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
_finish_undo();
@@ -970,17 +996,20 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else if (tool == TOOL_MOVING) {
Point2 ofs = over_tile - rectangle.position;
+ Vector<int> ids;
_start_undo(TTR("Move"));
+ ids.push_back(TileMap::INVALID_CELL);
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), TileMap::INVALID_CELL, false, false, false);
+ _set_cell(Point2i(j, i), ids, false, false, false);
}
}
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose);
+ ids[0] = E->get().cell;
+ _set_cell(E->get().pos + ofs, ids, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
_finish_undo();
@@ -1003,7 +1032,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
undo_redo->create_action(TTR("Bucket Fill"));
Dictionary op;
- op["id"] = get_selected_tile();
+ op["id"] = get_selected_tiles();
op["flip_h"] = flip_h;
op["flip_v"] = flip_v;
op["transpose"] = transpose;
@@ -1079,7 +1108,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_ERASING;
- _set_cell(local, TileMap::INVALID_CELL);
+ _set_cell(local, invalid_cell);
}
return true;
@@ -1100,8 +1129,10 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else if (tool == TOOL_BUCKET) {
+ Vector<int> ids;
+ ids.push_back(node->get_cell(over_tile.x, over_tile.y));
Dictionary pop;
- pop["id"] = node->get_cell(over_tile.x, over_tile.y);
+ pop["id"] = ids;
pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
@@ -1149,7 +1180,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// Paint using bresenham line to prevent holes in painting if the user moves fast
Vector<Point2i> points = line(old_over_tile.x, over_tile.x, old_over_tile.y, over_tile.y);
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
for (int i = 0; i < points.size(); ++i) {
@@ -1159,7 +1190,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
paint_undo[pos] = _get_op_from_cell(pos);
}
- _set_cell(pos, id, flip_h, flip_v, transpose);
+ _set_cell(pos, ids, flip_h, flip_v, transpose);
}
return true;
@@ -1175,7 +1206,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Point2i pos = points[i];
- _set_cell(pos, TileMap::INVALID_CELL);
+ _set_cell(pos, invalid_cell);
}
return true;
@@ -1190,20 +1221,23 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (tool == TOOL_LINE_PAINT || tool == TOOL_LINE_ERASE) {
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
+ Vector<int> tmp_cell;
bool erasing = (tool == TOOL_LINE_ERASE);
+ tmp_cell.push_back(0);
if (erasing && paint_undo.size()) {
for (Map<Point2i, CellOp>::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);
+ tmp_cell[0] = E->get().idx;
+ _set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
}
paint_undo.clear();
- if (id != TileMap::INVALID_CELL) {
+ if (ids.size() > 0 && ids[0] != TileMap::INVALID_CELL) {
Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y);
@@ -1212,7 +1246,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
paint_undo[points[i]] = _get_op_from_cell(points[i]);
if (erasing)
- _set_cell(points[i], TileMap::INVALID_CELL);
+ _set_cell(points[i], invalid_cell);
}
canvas_item_editor->update();
@@ -1222,6 +1256,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
if (tool == TOOL_RECTANGLE_PAINT || tool == TOOL_RECTANGLE_ERASE) {
+ Vector<int> tmp_cell;
+ tmp_cell.push_back(0);
+
_select(rectangle_begin, over_tile);
if (tool == TOOL_RECTANGLE_ERASE) {
@@ -1230,7 +1267,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
for (Map<Point2i, CellOp>::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);
+ tmp_cell[0] = E->get().idx;
+ _set_cell(E->key(), tmp_cell, E->get().xf, E->get().yf, E->get().tr);
}
}
@@ -1242,7 +1280,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Point2i tile = Point2i(j, i);
paint_undo[tile] = _get_op_from_cell(tile);
- _set_cell(tile, TileMap::INVALID_CELL);
+ _set_cell(tile, invalid_cell);
}
}
}
@@ -1499,27 +1537,27 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
if (paint_undo.empty())
return;
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
- if (id == TileMap::INVALID_CELL)
+ if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL)
return;
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- _draw_cell(id, E->key(), flip_h, flip_v, transpose, xform);
+ _draw_cell(ids[0], E->key(), flip_h, flip_v, transpose, xform);
}
} else if (tool == TOOL_RECTANGLE_PAINT) {
- int id = get_selected_tile();
+ Vector<int> ids = get_selected_tiles();
- if (id == TileMap::INVALID_CELL)
+ if (ids.size() == 1 && ids[0] == TileMap::INVALID_CELL)
return;
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++) {
- _draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform);
+ _draw_cell(ids[0], Point2i(j, i), flip_h, flip_v, transpose, xform);
}
}
} else if (tool == TOOL_DUPLICATING || tool == TOOL_MOVING) {
@@ -1557,17 +1595,17 @@ void TileMapEditor::forward_draw_over_viewport(Control *p_overlay) {
} else if (tool == TOOL_BUCKET) {
- int tile = get_selected_tile();
- _draw_fill_preview(tile, over_tile, flip_h, flip_v, transpose, xform);
+ Vector<int> tiles = get_selected_tiles();
+ _draw_fill_preview(tiles[0], over_tile, flip_h, flip_v, transpose, xform);
} else {
- int st = get_selected_tile();
+ Vector<int> st = get_selected_tiles();
- if (st == TileMap::INVALID_CELL)
+ if (st.size() == 1 && st[0] == TileMap::INVALID_CELL)
return;
- _draw_cell(st, over_tile, flip_h, flip_v, transpose, xform);
+ _draw_cell(st[0], over_tile, flip_h, flip_v, transpose, xform);
}
}
}
@@ -1713,6 +1751,9 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
bucket_cache_tile = -1;
bucket_cache_visited = 0;
+ invalid_cell.resize(1);
+ invalid_cell[0] = TileMap::INVALID_CELL;
+
ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE);
ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F);
ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"), KEY_T);
@@ -1759,6 +1800,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
palette->set_max_columns(0);
palette->set_icon_mode(ItemList::ICON_MODE_TOP);
palette->set_max_text_lines(2);
+ palette->set_select_mode(ItemList::SELECT_MULTI);
palette->connect("item_selected", this, "_palette_selected");
palette_container->add_child(palette);
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 77e9a33892..b8443ca962 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -157,6 +157,7 @@ class TileMapEditor : public VBoxContainer {
List<TileData> copydata;
Map<Point2i, CellOp> undo_data;
+ Vector<int> invalid_cell;
void _pick_tile(const Point2 &p_pos);
@@ -173,8 +174,8 @@ class TileMapEditor : public VBoxContainer {
void _update_copydata();
- int get_selected_tile() const;
- void set_selected_tile(int p_tile);
+ Vector<int> get_selected_tiles() const;
+ void set_selected_tiles(Vector<int> p_tile);
void _manual_toggled(bool p_enabled);
void _text_entered(const String &p_text);
@@ -187,7 +188,7 @@ class TileMapEditor : public VBoxContainer {
void _start_undo(const String &p_action);
void _finish_undo();
void _create_set_cell_undo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new);
- void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false);
+ void _set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false);
void _canvas_mouse_enter();
void _canvas_mouse_exit();