From 88007e91cf063fa92eda5fb6e3f504fc210a36f9 Mon Sep 17 00:00:00 2001 From: Bernhard Liebl Date: Sat, 4 Nov 2017 14:46:49 +0100 Subject: [PATCH] Use AbstractPolygon2DEditor for Line2D --- editor/plugins/abstract_polygon_2d_editor.cpp | 135 ++++++--- editor/plugins/abstract_polygon_2d_editor.h | 5 + editor/plugins/line_2d_editor_plugin.cpp | 257 ++---------------- editor/plugins/line_2d_editor_plugin.h | 68 +---- 4 files changed, 136 insertions(+), 329 deletions(-) diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 2f839b96cfe..f2f913d2b3d 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -92,6 +92,11 @@ bool AbstractPolygon2DEditor::_is_empty() const { return true; } +bool AbstractPolygon2DEditor::_is_line() const { + + return false; +} + int AbstractPolygon2DEditor::_get_polygon_count() const { return 1; @@ -158,12 +163,23 @@ void AbstractPolygon2DEditor::_menu_option(int p_option) { mode = MODE_CREATE; button_create->set_pressed(true); button_edit->set_pressed(false); + button_delete->set_pressed(false); } break; case MODE_EDIT: { + wip_active = false; mode = MODE_EDIT; button_create->set_pressed(false); button_edit->set_pressed(true); + button_delete->set_pressed(false); + } break; + case MODE_DELETE: { + + wip_active = false; + mode = MODE_DELETE; + button_create->set_pressed(false); + button_edit->set_pressed(false); + button_delete->set_pressed(true); } break; } } @@ -174,8 +190,9 @@ void AbstractPolygon2DEditor::_notification(int p_what) { case NOTIFICATION_READY: { - button_create->set_icon(get_icon("Edit", "EditorIcons")); - button_edit->set_icon(get_icon("MovePoint", "EditorIcons")); + button_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate", "EditorIcons")); + button_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit", "EditorIcons")); + button_delete->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete", "EditorIcons")); button_edit->set_pressed(true); get_tree()->connect("node_removed", this, "_node_removed"); @@ -199,19 +216,32 @@ void AbstractPolygon2DEditor::_node_removed(Node *p_node) { } } -void AbstractPolygon2DEditor::_wip_close() { +void AbstractPolygon2DEditor::_wip_changed() { - if (wip.size() >= 3) { + if (wip_active && _is_line()) { + _set_polygon(0, wip); + } +} + +void AbstractPolygon2DEditor::_wip_close() { + if (_is_line()) { + + _set_polygon(0, wip); + } else if (wip.size() >= 3) { undo_redo->create_action(TTR("Create Poly")); _action_add_polygon(wip); _commit_action(); + } else { - mode = MODE_EDIT; - button_edit->set_pressed(true); - button_create->set_pressed(false); + return; } + mode = MODE_EDIT; + button_edit->set_pressed(true); + button_create->set_pressed(false); + button_delete->set_pressed(false); + wip.clear(); wip_active = false; @@ -252,6 +282,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref &p_event) wip.clear(); wip.push_back(cpoint); wip_active = true; + _wip_changed(); edited_point = PosVertex(-1, 1, cpoint); canvas_item_editor->get_viewport_control()->update(); hover_point = Vertex(); @@ -262,20 +293,20 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref &p_event) const real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); - if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_threshold) { + if (!_is_line() && wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_threshold) { //wip closed _wip_close(); return true; } else { + //add wip point wip.push_back(cpoint); + _wip_changed(); edited_point = PosVertex(-1, wip.size(), cpoint); selected_point = Vertex(wip.size() - 1); canvas_item_editor->get_viewport_control()->update(); return true; - - //add wip point } } } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) { @@ -356,6 +387,18 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref &p_event) const PosVertex closest = closest_point(gpoint); + if (closest.valid()) { + + remove_point(closest); + return true; + } + } + } else if (mode == MODE_DELETE) { + + if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) { + + const PosVertex closest = closest_point(gpoint); + if (closest.valid()) { remove_point(closest); @@ -414,25 +457,33 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref &p_event) Ref k = p_event; - if (k.is_valid() && k->is_pressed() && (k->get_scancode() == KEY_DELETE || k->get_scancode() == KEY_BACKSPACE)) { - if (wip_active && selected_point.polygon == -1) { + if (k.is_valid() && k->is_pressed()) { - if (wip.size() > selected_point.vertex) { + if (k->get_scancode() == KEY_DELETE || k->get_scancode() == KEY_BACKSPACE) { - wip.remove(selected_point.vertex); - selected_point = wip.size() - 1; - canvas_item_editor->get_viewport_control()->update(); - return true; + if (wip_active && selected_point.polygon == -1) { + + if (wip.size() > selected_point.vertex) { + + wip.remove(selected_point.vertex); + _wip_changed(); + selected_point = wip.size() - 1; + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } else { + + const Vertex active_point = get_active_point(); + + if (active_point.valid()) { + + remove_point(active_point); + return true; + } } - } else { + } else if (wip_active && k->get_scancode() == KEY_ENTER) { - const Vertex active_point = get_active_point(); - - if (active_point.valid()) { - - remove_point(active_point); - return true; - } + _wip_close(); } } @@ -451,6 +502,7 @@ void AbstractPolygon2DEditor::forward_draw_over_canvas(Control *p_canvas) { const Vertex active_point = get_active_point(); const int n_polygons = _get_polygon_count(); + const bool is_closed = !_is_line(); for (int j = -1; j < n_polygons; j++) { @@ -476,7 +528,7 @@ void AbstractPolygon2DEditor::forward_draw_over_canvas(Control *p_canvas) { const Color col = Color(0.5, 0.5, 0.5); // FIXME polygon->get_outline_color(); const int n = pre_move_edit.size(); - for (int i = 0; i < n; i++) { + for (int i = 0; i < n - is_closed ? 0 : 1; i++) { Vector2 p, p2; p = pre_move_edit[i] + offset; @@ -496,17 +548,22 @@ void AbstractPolygon2DEditor::forward_draw_over_canvas(Control *p_canvas) { const Vertex vertex(j, i); - Vector2 p, p2; - p = (vertex == edited_point) ? edited_point.pos : (points[i] + offset); - if (j == edited_point.polygon && ((wip_active && i == n_points - 1) || (((i + 1) % n_points) == edited_point.vertex))) - p2 = edited_point.pos; - else - p2 = points[(i + 1) % n_points] + offset; + const Vector2 p = (vertex == edited_point) ? edited_point.pos : (points[i] + offset); + const Vector2 point = xform.xform(p); - Vector2 point = xform.xform(p); - Vector2 next_point = xform.xform(p2); + if (is_closed || i < n_points - 1) { + + Vector2 p2; + if (j == edited_point.polygon && + ((wip_active && i == n_points - 1) || (((i + 1) % n_points) == edited_point.vertex))) + p2 = edited_point.pos; + else + p2 = points[(i + 1) % n_points] + offset; + + const Vector2 next_point = xform.xform(p2); + vpc->draw_line(point, next_point, col, 2); + } - vpc->draw_line(point, next_point, col, 2); Ref handle = vertex == active_point ? selected_handle : default_handle; vpc->draw_texture(handle, point - handle->get_size() * 0.5); } @@ -674,7 +731,7 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wi add_child(button_create); button_create->connect("pressed", this, "_menu_option", varray(MODE_CREATE)); button_create->set_toggle_mode(true); - button_create->set_tooltip(TTR("Create a new polygon from scratch.")); + button_create->set_tooltip(TTR("Create a new polygon from scratch")); button_edit = memnew(ToolButton); add_child(button_edit); @@ -682,6 +739,12 @@ AbstractPolygon2DEditor::AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wi button_edit->set_toggle_mode(true); button_edit->set_tooltip(TTR("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point.")); + button_delete = memnew(ToolButton); + add_child(button_delete); + button_delete->connect("pressed", this, "_menu_option", varray(MODE_DELETE)); + button_delete->set_toggle_mode(true); + button_delete->set_tooltip(TTR("Delete points")); + create_resource = memnew(ConfirmationDialog); add_child(create_resource); create_resource->get_ok()->set_text(TTR("Create")); diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h index 8dd22958db7..915fe0803e3 100644 --- a/editor/plugins/abstract_polygon_2d_editor.h +++ b/editor/plugins/abstract_polygon_2d_editor.h @@ -46,6 +46,7 @@ class AbstractPolygon2DEditor : public HBoxContainer { ToolButton *button_create; ToolButton *button_edit; + ToolButton *button_delete; struct Vertex { Vertex(); @@ -89,6 +90,7 @@ protected: MODE_CREATE, MODE_EDIT, + MODE_DELETE, MODE_CONT, }; @@ -98,7 +100,9 @@ protected: UndoRedo *undo_redo; virtual void _menu_option(int p_option); + void _wip_changed(); void _wip_close(); + bool _delete_point(const Vector2 &p_gpoint); void _notification(int p_what); void _node_removed(Node *p_node); @@ -116,6 +120,7 @@ protected: virtual Node2D *_get_node() const = 0; virtual void _set_node(Node *p_polygon) = 0; + virtual bool _is_line() const; virtual int _get_polygon_count() const; virtual Vector2 _get_offset(int p_idx) const; virtual Variant _get_polygon(int p_idx) const; diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp index 0533aaa9c03..51fa488b43b 100644 --- a/editor/plugins/line_2d_editor_plugin.cpp +++ b/editor/plugins/line_2d_editor_plugin.cpp @@ -29,259 +29,42 @@ /*************************************************************************/ #include "line_2d_editor_plugin.h" -#include "canvas_item_editor_plugin.h" -#include "editor/editor_settings.h" -#include "os/file_access.h" -#include "os/keyboard.h" +Node2D *Line2DEditor::_get_node() const { -//---------------------------------------------------------------------------- -// Line2DEditor -//---------------------------------------------------------------------------- - -void Line2DEditor::_node_removed(Node *p_node) { - if (p_node == node) { - node = NULL; - hide(); - } + return node; } -void Line2DEditor::_notification(int p_what) { - switch (p_what) { - case NOTIFICATION_VISIBILITY_CHANGED: - // This widget is not a child but should have the same visibility state - base_hb->set_visible(is_visible()); - break; - } +void Line2DEditor::_set_node(Node *p_line) { + + node = Object::cast_to(p_line); } -int Line2DEditor::get_point_index_at(const Transform2D &xform, Vector2 gpos) { - ERR_FAIL_COND_V(node == 0, -1); +bool Line2DEditor::_is_line() const { - real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8); - - for (int i = 0; i < node->get_point_count(); ++i) { - Point2 p = xform.xform(node->get_point_position(i)); - if (gpos.distance_to(p) < grab_threshold) { - return i; - } - } - - return -1; + return true; } -bool Line2DEditor::forward_canvas_gui_input(const Ref &p_event) { +Variant Line2DEditor::_get_polygon(int p_idx) const { - if (!node) - return false; - - if (!node->is_visible()) - return false; - - Ref mb = p_event; - - if (mb.is_valid()) { - - Vector2 gpoint = mb->get_position(); - Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position()))); - - if (mb->is_pressed() && _dragging == false) { - int i = get_point_index_at(canvas_item_editor->get_canvas_transform() * node->get_global_transform(), gpoint); - if (i != -1) { - if (mb->get_button_index() == BUTTON_LEFT && !mb->get_shift() && mode == MODE_EDIT) { - _dragging = true; - action_point = i; - moving_from = node->get_point_position(i); - moving_screen_from = gpoint; - } else if ((mb->get_button_index() == BUTTON_RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == BUTTON_LEFT && mode == MODE_DELETE)) { - undo_redo->create_action(TTR("Remove Point from Line2D")); - undo_redo->add_do_method(node, "remove_point", i); - undo_redo->add_undo_method(node, "add_point", node->get_point_position(i), i); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->commit_action(); - } - return true; - } - } - - if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) { - - undo_redo->create_action(TTR("Add Point to Line2D")); - undo_redo->add_do_method(node, "add_point", cpoint); - undo_redo->add_undo_method(node, "remove_point", node->get_point_count()); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->commit_action(); - - _dragging = true; - action_point = node->get_point_count() - 1; - moving_from = node->get_point_position(action_point); - moving_screen_from = gpoint; - - canvas_item_editor->get_viewport_control()->update(); - - return true; - } - - if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && _dragging) { - undo_redo->create_action(TTR("Move Point in Line2D")); - undo_redo->add_do_method(node, "set_point_position", action_point, cpoint); - undo_redo->add_undo_method(node, "set_point_position", action_point, moving_from); - undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update"); - undo_redo->commit_action(); - _dragging = false; - return true; - } - } - - Ref mm = p_event; - - if (mm.is_valid()) { - - if (_dragging) { - Vector2 gpoint = mm->get_position(); - Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position()))); - node->set_point_position(action_point, cpoint); - canvas_item_editor->get_viewport_control()->update(); - return true; - } - } - - return false; + return _get_node()->get("points"); } -void Line2DEditor::forward_draw_over_canvas(Control *p_canvas) { +void Line2DEditor::_set_polygon(int p_idx, const Variant &p_polygon) const { - if (!node) - return; - - if (!node->is_visible()) - return; - - Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); - Ref handle = get_icon("EditorHandle", "EditorIcons"); - Size2 handle_size = handle->get_size(); - - int len = node->get_point_count(); - Control *vpc = canvas_item_editor->get_viewport_control(); - - for (int i = 0; i < len; ++i) { - Vector2 point = xform.xform(node->get_point_position(i)); - vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false); - } + _get_node()->set("points", p_polygon); } -void Line2DEditor::_node_visibility_changed() { - if (!node) - return; - canvas_item_editor->get_viewport_control()->update(); +void Line2DEditor::_action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon) { + + Node2D *node = _get_node(); + undo_redo->add_do_method(node, "set_points", p_polygon); + undo_redo->add_undo_method(node, "set_points", p_previous); } -void Line2DEditor::edit(Node *p_line2d) { - - if (!canvas_item_editor) - canvas_item_editor = CanvasItemEditor::get_singleton(); - - if (p_line2d) { - node = Object::cast_to(p_line2d); - if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) - node->connect("visibility_changed", this, "_node_visibility_changed"); - } else { - // node may have been deleted at this point - if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed")) - node->disconnect("visibility_changed", this, "_node_visibility_changed"); - node = NULL; - } +Line2DEditor::Line2DEditor(EditorNode *p_editor) + : AbstractPolygon2DEditor(p_editor) { } -void Line2DEditor::_bind_methods() { - ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Line2DEditor::_node_visibility_changed); - ClassDB::bind_method(D_METHOD("_mode_selected"), &Line2DEditor::_mode_selected); -} - -void Line2DEditor::_mode_selected(int p_mode) { - for (int i = 0; i < _MODE_COUNT; ++i) { - toolbar_buttons[i]->set_pressed(i == p_mode); - } - mode = Mode(p_mode); -} - -Line2DEditor::Line2DEditor(EditorNode *p_editor) { - - canvas_item_editor = NULL; - editor = p_editor; - undo_redo = editor->get_undo_redo(); - - _dragging = false; - - base_hb = memnew(HBoxContainer); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(base_hb); - - sep = memnew(VSeparator); - base_hb->add_child(sep); - - { - ToolButton *b = memnew(ToolButton); - b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit", "EditorIcons")); - b->set_toggle_mode(true); - b->set_focus_mode(Control::FOCUS_NONE); - b->set_tooltip( - TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point")); - b->connect("pressed", this, "_mode_selected", varray(MODE_EDIT)); - toolbar_buttons[MODE_EDIT] = b; - base_hb->add_child(b); - } - - { - ToolButton *b = memnew(ToolButton); - b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate", "EditorIcons")); - b->set_toggle_mode(true); - b->set_focus_mode(Control::FOCUS_NONE); - b->set_tooltip(TTR("Add Point (in empty space)") + "\n" + TTR("Split Segment (in line)")); - b->connect("pressed", this, "_mode_selected", varray(MODE_CREATE)); - toolbar_buttons[MODE_CREATE] = b; - base_hb->add_child(b); - } - - { - ToolButton *b = memnew(ToolButton); - b->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete", "EditorIcons")); - b->set_toggle_mode(true); - b->set_focus_mode(Control::FOCUS_NONE); - b->set_tooltip(TTR("Delete Point")); - b->connect("pressed", this, "_mode_selected", varray(MODE_DELETE)); - toolbar_buttons[MODE_DELETE] = b; - base_hb->add_child(b); - } - - base_hb->hide(); - hide(); - - _mode_selected(MODE_CREATE); -} - -//---------------------------------------------------------------------------- -// Line2DEditorPlugin -//---------------------------------------------------------------------------- - -void Line2DEditorPlugin::edit(Object *p_object) { - line2d_editor->edit(Object::cast_to(p_object)); -} - -bool Line2DEditorPlugin::handles(Object *p_object) const { - return p_object->is_class("Line2D"); -} - -void Line2DEditorPlugin::make_visible(bool p_visible) { - line2d_editor->set_visible(p_visible); - if (p_visible == false) - line2d_editor->edit(NULL); -} - -Line2DEditorPlugin::Line2DEditorPlugin(EditorNode *p_node) { - editor = p_node; - line2d_editor = memnew(Line2DEditor(p_node)); - CanvasItemEditor::get_singleton()->add_control_to_menu_panel(line2d_editor); - line2d_editor->hide(); +Line2DEditorPlugin::Line2DEditorPlugin(EditorNode *p_node) + : AbstractPolygon2DEditorPlugin(p_node, memnew(Line2DEditor(p_node)), "Line2D") { } diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h index 6858680aed0..24c19c420d1 100644 --- a/editor/plugins/line_2d_editor_plugin.h +++ b/editor/plugins/line_2d_editor_plugin.h @@ -30,78 +30,34 @@ #ifndef LINE_2D_EDITOR_PLUGIN_H #define LINE_2D_EDITOR_PLUGIN_H -#include "editor/editor_node.h" -#include "editor/editor_plugin.h" +#include "editor/plugins/abstract_polygon_2d_editor.h" #include "scene/2d/line_2d.h" -#include "scene/2d/path_2d.h" -#include "scene/gui/tool_button.h" -class CanvasItemEditor; +class Line2DEditor : public AbstractPolygon2DEditor { -class Line2DEditor : public HBoxContainer { - GDCLASS(Line2DEditor, HBoxContainer) -private: - void _mode_selected(int p_mode); - void _node_visibility_changed(); + GDCLASS(Line2DEditor, AbstractPolygon2DEditor); - int get_point_index_at(const Transform2D &xform, Vector2 gpos); - - UndoRedo *undo_redo; - - CanvasItemEditor *canvas_item_editor; - EditorNode *editor; - Panel *panel; Line2D *node; - HBoxContainer *base_hb; - Separator *sep; - - enum Mode { - MODE_CREATE = 0, - MODE_EDIT, - MODE_DELETE, - _MODE_COUNT - }; - - Mode mode; - ToolButton *toolbar_buttons[_MODE_COUNT]; - - bool _dragging; - int action_point; - Point2 moving_from; - Point2 moving_screen_from; - protected: - void _node_removed(Node *p_node); - void _notification(int p_what); + virtual Node2D *_get_node() const; + virtual void _set_node(Node *p_line); - static void _bind_methods(); + virtual bool _is_line() const; + virtual Variant _get_polygon(int p_idx) const; + virtual void _set_polygon(int p_idx, const Variant &p_polygon) const; + virtual void _action_set_polygon(int p_idx, const Variant &p_previous, const Variant &p_polygon); public: - bool forward_canvas_gui_input(const Ref &p_event); - void forward_draw_over_canvas(Control *p_canvas); - void edit(Node *p_line2d); Line2DEditor(EditorNode *p_editor); }; -class Line2DEditorPlugin : public EditorPlugin { - GDCLASS(Line2DEditorPlugin, EditorPlugin) +class Line2DEditorPlugin : public AbstractPolygon2DEditorPlugin { + + GDCLASS(Line2DEditorPlugin, AbstractPolygon2DEditorPlugin); public: - virtual bool forward_canvas_gui_input(const Ref &p_event) { return line2d_editor->forward_canvas_gui_input(p_event); } - virtual void forward_draw_over_canvas(Control *p_canvas) { return line2d_editor->forward_draw_over_canvas(p_canvas); } - - virtual String get_name() const { return "Line2D"; } - bool has_main_screen() const { return false; } - virtual void edit(Object *p_object); - virtual bool handles(Object *p_object) const; - virtual void make_visible(bool p_visible); - Line2DEditorPlugin(EditorNode *p_node); - -private: - Line2DEditor *line2d_editor; - EditorNode *editor; }; #endif // LINE_2D_EDITOR_PLUGIN_H