diff options
author | RĂ©mi Verschelde <rverschelde@gmail.com> | 2017-02-12 23:30:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-12 23:30:04 +0100 |
commit | 117a83fcb916cb02777dea73fb642216fd2e1d79 (patch) | |
tree | 1c50d003af87ab2fe00a73ef23e90e7ef97fdb3e /tools/editor | |
parent | 37e75873ef88443a565d371ec638f554d92d4293 (diff) | |
parent | e2fba10b952f694f604e20b9e5f220023a5f8fd2 (diff) |
Merge pull request #7352 from Zylann/polyline
Polyline
Diffstat (limited to 'tools/editor')
-rw-r--r-- | tools/editor/editor_node.cpp | 2 | ||||
-rw-r--r-- | tools/editor/icons/2x/icon_line_2d.png | bin | 0 -> 795 bytes | |||
-rw-r--r-- | tools/editor/icons/icon_line_2d.png | bin | 0 -> 474 bytes | |||
-rw-r--r-- | tools/editor/icons/source/icon_line_2d.svg | 82 | ||||
-rw-r--r-- | tools/editor/plugins/line_2d_editor_plugin.cpp | 283 | ||||
-rw-r--r-- | tools/editor/plugins/line_2d_editor_plugin.h | 85 |
6 files changed, 452 insertions, 0 deletions
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 952681c5eb..9fac8dfbeb 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -87,6 +87,7 @@ #include "plugins/script_editor_plugin.h" #include "plugins/script_text_editor.h" #include "plugins/path_2d_editor_plugin.h" +#include "plugins/line_2d_editor_plugin.h" #include "plugins/particles_editor_plugin.h" #include "plugins/particles_2d_editor_plugin.h" #include "plugins/animation_tree_editor_plugin.h" @@ -6350,6 +6351,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( Path2DEditorPlugin(this) ) ); //add_editor_plugin( memnew( PathEditorPlugin(this) ) ); //add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) ); + add_editor_plugin( memnew( Line2DEditorPlugin(this) ) ); add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) ); add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) ); add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) ); diff --git a/tools/editor/icons/2x/icon_line_2d.png b/tools/editor/icons/2x/icon_line_2d.png Binary files differnew file mode 100644 index 0000000000..27299a2b69 --- /dev/null +++ b/tools/editor/icons/2x/icon_line_2d.png diff --git a/tools/editor/icons/icon_line_2d.png b/tools/editor/icons/icon_line_2d.png Binary files differnew file mode 100644 index 0000000000..4ebf46af04 --- /dev/null +++ b/tools/editor/icons/icon_line_2d.png diff --git a/tools/editor/icons/source/icon_line_2d.svg b/tools/editor/icons/source/icon_line_2d.svg new file mode 100644 index 0000000000..7f833f4a9c --- /dev/null +++ b/tools/editor/icons/source/icon_line_2d.svg @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="16" + height="16" + viewBox="0 0 16 16" + id="svg2" + version="1.1" + inkscape:version="0.91 r13725" + inkscape:export-filename="D:\PROJETS\INFO\GODOT\ENGINE\godot_fork\tools\editor\icons\2x\icon_line_2d.png" + inkscape:export-xdpi="180" + inkscape:export-ydpi="180" + sodipodi:docname="icon_line_2d.svg"> + <defs + id="defs4" /> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="31.999999" + inkscape:cx="7.5587317" + inkscape:cy="9.1781644" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + units="px" + inkscape:snap-bbox="true" + inkscape:bbox-paths="true" + inkscape:bbox-nodes="true" + inkscape:snap-bbox-edge-midpoints="true" + inkscape:snap-bbox-midpoints="true" + inkscape:snap-object-midpoints="true" + inkscape:snap-center="true" + inkscape:window-width="1920" + inkscape:window-height="1017" + inkscape:window-x="-8" + inkscape:window-y="32" + inkscape:window-maximized="1" + inkscape:snap-grids="true" + inkscape:object-nodes="true" + showguides="false"> + <inkscape:grid + type="xygrid" + id="grid3336" + empspacing="4" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(0,-1036.3622)"> + <path + style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#a5b7f3;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.98823529" + d="m 2,1045.3622 3,4 3,-10 3,6 3,-2" + id="path4135" + inkscape:connector-curvature="0" + sodipodi:nodetypes="ccccc" /> + </g> +</svg> diff --git a/tools/editor/plugins/line_2d_editor_plugin.cpp b/tools/editor/plugins/line_2d_editor_plugin.cpp new file mode 100644 index 0000000000..054a2c62e0 --- /dev/null +++ b/tools/editor/plugins/line_2d_editor_plugin.cpp @@ -0,0 +1,283 @@ +#include "line_2d_editor_plugin.h" + +#include "canvas_item_editor_plugin.h" +#include "os/file_access.h" +#include "tools/editor/editor_settings.h" +#include "os/keyboard.h" + + +//---------------------------------------------------------------------------- +// Line2DEditor +//---------------------------------------------------------------------------- + +void Line2DEditor::_node_removed(Node *p_node) { + if(p_node == node) { + node=NULL; + hide(); + } +} + +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; + } +} + +Vector2 Line2DEditor::mouse_to_local_pos(Vector2 gpoint, bool alt) { + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + return !alt? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) + : node->get_global_transform().affine_inverse().xform( + canvas_item_editor->snap_point( + canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)) ); +} + +int Line2DEditor::get_point_index_at(Vector2 gpos) { + ERR_FAIL_COND_V(node == 0, -1); + + real_t grab_treshold = EDITOR_DEF("poly_editor/point_grab_radius", 8); + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + + for(int i = 0; i < node->get_point_count(); ++i) { + Point2 p = xform.xform( node->get_point_pos(i) ); + if(gpos.distance_to(p) < grab_treshold) { + return i; + } + } + + return -1; +} + +bool Line2DEditor::forward_input_event(const InputEvent& p_event) { + + if (!node) + return false; + + if (!node->is_visible()) + return false; + + switch(p_event.type) { + + case InputEvent::MOUSE_BUTTON: { + + const InputEventMouseButton &mb = p_event.mouse_button; + + Vector2 gpoint = Point2(mb.x,mb.y); + Vector2 cpoint = mouse_to_local_pos(gpoint, mb.mod.alt); + + if(mb.pressed && _dragging == false) { + int i = get_point_index_at(gpoint); + if(i != -1) { + if (mb.button_index == BUTTON_LEFT && !mb.mod.shift && mode == MODE_EDIT) { + _dragging = true; + action_point = i; + moving_from = node->get_point_pos(i); + moving_screen_from = gpoint; + } + else if((mb.button_index == BUTTON_RIGHT && mode == MODE_EDIT) || (mb.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_pos(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.pressed && mb.button_index == BUTTON_LEFT && ((mb.mod.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_pos(action_point); + moving_screen_from = gpoint; + + canvas_item_editor->get_viewport_control()->update(); + + return true; + } + + if(!mb.pressed && mb.button_index == BUTTON_LEFT && _dragging) { + undo_redo->create_action(TTR("Move Point in Line2D")); + undo_redo->add_do_method(node, "set_point_pos", action_point, cpoint); + undo_redo->add_undo_method(node, "set_point_pos", 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; + } + } + break; + + case InputEvent::MOUSE_MOTION: { + if (_dragging) { + const InputEventMouseMotion &mm = p_event.mouse_motion; + Vector2 cpoint = mouse_to_local_pos(Vector2(mm.x, mm.y), mm.mod.alt); + node->set_point_pos(action_point,cpoint); + canvas_item_editor->get_viewport_control()->update(); + return true; + } + } + break; + } + + return false; +} + +void Line2DEditor::_canvas_draw() { + + if (!node) + return; + + if (!node->is_visible()) + return; + + Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform(); + Ref<Texture> 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_pos(i)); + vpc->draw_texture_rect(handle, Rect2(point - handle_size * 0.5, handle_size), false); + } +} + +void Line2DEditor::_node_visibility_changed() { + if (!node) + return; + canvas_item_editor->get_viewport_control()->update(); +} + +void Line2DEditor::edit(Node *p_line2d) { + + if (!canvas_item_editor) + canvas_item_editor = CanvasItemEditor::get_singleton(); + + if (p_line2d) { + node = p_line2d->cast_to<Line2D>(); + if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw")) + canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw"); + if (!node->is_connected("visibility_changed", this, "_node_visibility_changed")) + node->connect("visibility_changed", this, "_node_visibility_changed"); + } + else { + if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw")) + canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw"); + // 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; + } +} + +void Line2DEditor::_bind_methods() { + ClassDB::bind_method(_MD("_canvas_draw"), &Line2DEditor::_canvas_draw); + ClassDB::bind_method(_MD("_node_visibility_changed"), &Line2DEditor::_node_visibility_changed); + ClassDB::bind_method(_MD("_mode_selected"), &Line2DEditor::_mode_selected); +} + +void Line2DEditor::_mode_selected(int p_mode) { + for(unsigned 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(p_object->cast_to<Node>()); +} + +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(); +} + + diff --git a/tools/editor/plugins/line_2d_editor_plugin.h b/tools/editor/plugins/line_2d_editor_plugin.h new file mode 100644 index 0000000000..0df64208a8 --- /dev/null +++ b/tools/editor/plugins/line_2d_editor_plugin.h @@ -0,0 +1,85 @@ +#ifndef LINE_2D_EDITOR_PLUGIN_H +#define LINE_2D_EDITOR_PLUGIN_H + +#include "tools/editor/editor_plugin.h" +#include "tools/editor/editor_node.h" +#include "scene/2d/path_2d.h" +#include "scene/gui/tool_button.h" +#include "scene/gui/button_group.h" +#include "scene/2d/line_2d.h" + + +class CanvasItemEditor; + +class Line2DEditor : public HBoxContainer { + GDCLASS(Line2DEditor, HBoxContainer) + +public: + bool forward_input_event(const InputEvent& p_event); + void edit(Node *p_line2d); + Line2DEditor(EditorNode *p_editor); + +protected: + void _node_removed(Node *p_node); + void _notification(int p_what); + + Vector2 mouse_to_local_pos(Vector2 mpos); + + static void _bind_methods(); + +private: + void _mode_selected(int p_mode); + void _canvas_draw(); + void _node_visibility_changed(); + + int get_point_index_at(Vector2 gpos); + Vector2 mouse_to_local_pos(Vector2 gpos, bool alt); + + 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; +}; + +class Line2DEditorPlugin : public EditorPlugin { + GDCLASS( Line2DEditorPlugin, EditorPlugin ) + +public: + virtual bool forward_canvas_input_event(const Transform2D& p_canvas_xform,const InputEvent& p_event) { return line2d_editor->forward_input_event(p_event); } + + virtual String get_name() const { return "Line2D"; } + bool has_main_screen() const { return false; } + virtual void edit(Object *p_node); + virtual bool handles(Object *p_node) const; + virtual void make_visible(bool p_visible); + + Line2DEditorPlugin(EditorNode *p_node); + +private: + Line2DEditor *line2d_editor; + EditorNode *editor; + +}; + +#endif // LINE_2D_EDITOR_PLUGIN_H + |