summaryrefslogtreecommitdiff
path: root/tools/editor
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <rverschelde@gmail.com>2017-02-12 23:30:04 +0100
committerGitHub <noreply@github.com>2017-02-12 23:30:04 +0100
commit117a83fcb916cb02777dea73fb642216fd2e1d79 (patch)
tree1c50d003af87ab2fe00a73ef23e90e7ef97fdb3e /tools/editor
parent37e75873ef88443a565d371ec638f554d92d4293 (diff)
parente2fba10b952f694f604e20b9e5f220023a5f8fd2 (diff)
Merge pull request #7352 from Zylann/polyline
Polyline
Diffstat (limited to 'tools/editor')
-rw-r--r--tools/editor/editor_node.cpp2
-rw-r--r--tools/editor/icons/2x/icon_line_2d.pngbin0 -> 795 bytes
-rw-r--r--tools/editor/icons/icon_line_2d.pngbin0 -> 474 bytes
-rw-r--r--tools/editor/icons/source/icon_line_2d.svg82
-rw-r--r--tools/editor/plugins/line_2d_editor_plugin.cpp283
-rw-r--r--tools/editor/plugins/line_2d_editor_plugin.h85
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
new file mode 100644
index 0000000000..27299a2b69
--- /dev/null
+++ b/tools/editor/icons/2x/icon_line_2d.png
Binary files differ
diff --git a/tools/editor/icons/icon_line_2d.png b/tools/editor/icons/icon_line_2d.png
new file mode 100644
index 0000000000..4ebf46af04
--- /dev/null
+++ b/tools/editor/icons/icon_line_2d.png
Binary files differ
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
+