diff options
-rw-r--r-- | editor/editor_export.h | 1 | ||||
-rw-r--r-- | editor/editor_plugin.cpp | 4 | ||||
-rw-r--r-- | editor/editor_run_native.cpp | 2 | ||||
-rw-r--r-- | editor/editor_settings.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/curve_editor_plugin.cpp | 82 | ||||
-rw-r--r-- | editor/plugins/curve_editor_plugin.h | 2 | ||||
-rw-r--r-- | methods.py | 35 | ||||
-rw-r--r-- | platform/android/export/export.cpp | 12 | ||||
-rw-r--r-- | platform/android/run_icon.png | bin | 0 -> 636 bytes | |||
-rw-r--r-- | platform/javascript/export/export.cpp | 41 | ||||
-rw-r--r-- | platform/javascript/run_icon.png | bin | 0 -> 471 bytes | |||
-rw-r--r-- | scene/resources/curve.cpp | 46 | ||||
-rw-r--r-- | scene/resources/curve.h | 30 |
13 files changed, 172 insertions, 85 deletions
diff --git a/editor/editor_export.h b/editor/editor_export.h index 740f05174b..64381fbb35 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -197,6 +197,7 @@ public: }; virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { return OK; } + virtual Ref<Texture> get_run_icon() const { return get_logo(); } virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const = 0; diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 75ab1e8a44..e4b055a9e2 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -284,12 +284,12 @@ void EditorPlugin::save_global_state() {} void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer) { ResourceFormatImporter::get_singleton()->add_importer(p_importer); - EditorFileSystem::get_singleton()->scan_changes(); + EditorFileSystem::get_singleton()->scan(); } void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin> &p_importer) { ResourceFormatImporter::get_singleton()->remove_importer(p_importer); - EditorFileSystem::get_singleton()->scan_changes(); + EditorFileSystem::get_singleton()->scan(); } void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) { diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 4a767621ef..52b7e6992d 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -41,7 +41,7 @@ void EditorRunNative::_notification(int p_what) { Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(i); if (eep.is_null()) continue; - Ref<ImageTexture> icon = eep->get_logo(); + Ref<ImageTexture> icon = eep->get_run_icon(); if (!icon.is_null()) { Ref<Image> im = icon->get_data(); im = im->duplicate(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 5e950f003b..5c6ba892cb 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -737,7 +737,7 @@ void EditorSettings::_load_default_text_editor_theme() { set("text_editor/highlighting/string_color", Color::html("ef6ebe")); set("text_editor/highlighting/number_color", Color::html("EB9532")); set("text_editor/highlighting/symbol_color", Color::html("badfff")); - set("text_editor/highlighting/selection_color", Color::html("7b5dbe")); + set("text_editor/highlighting/selection_color", Color::html("6ca9c2")); set("text_editor/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2)); set("text_editor/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15)); set("text_editor/highlighting/line_length_guideline_color", Color(0.3, 0.5, 0.8, 0.1)); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 6b0da50927..d729bb7b76 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -133,7 +133,16 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { if (!mb.is_pressed() && _dragging && mb.get_button_index() == BUTTON_LEFT) { _dragging = false; if (_has_undo_data) { - push_undo(_undo_data); + + UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); + + ur.create_action(_selected_tangent == TANGENT_NONE ? TTR("Modify Curve Point") : TTR("Modify Curve Tangent")); + ur.add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data()); + ur.add_undo_method(*_curve_ref, "_set_data", _undo_data); + // Note: this will trigger one more "changed" signal even if nothing changes, + // but it's ok since it would have fired every frame during the drag anyways + ur.commit_action(); + _has_undo_data = false; } } @@ -152,7 +161,8 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { if (_selected_point != -1) { if (!_has_undo_data) { - // Save curve state before dragging points + // Save full curve state before dragging points, + // because this operation can modify their order _undo_data = curve.get_data(); _has_undo_data = true; } @@ -175,8 +185,6 @@ void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) { curve.set_point_value(_selected_point, point_pos.y); - //auto_calculate_tangents(i); - } else { // Drag tangent @@ -275,7 +283,13 @@ void CurveEditor::on_preset_item_selected(int preset_id) { break; } - push_undo(previous_data); + UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); + ur.create_action(TTR("Load Curve Preset")); + + ur.add_do_method(&curve, "_set_data", curve.get_data()); + ur.add_undo_method(&curve, "_set_data", previous_data); + + ur.commit_action(); } void CurveEditor::_curve_changed() { @@ -397,7 +411,8 @@ CurveEditor::TangentIndex CurveEditor::get_tangent_at(Vector2 pos) const { void CurveEditor::add_point(Vector2 pos) { ERR_FAIL_COND(_curve_ref.is_null()); - Array prev_data = _curve_ref->get_data(); + UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); + ur.create_action(TTR("Remove Curve Point")); Vector2 point_pos = get_world_pos(pos); if (point_pos.y < 0.0) @@ -405,41 +420,64 @@ void CurveEditor::add_point(Vector2 pos) { else if (point_pos.y > 1.0) point_pos.y = 1.0; - _curve_ref->add_point(point_pos); + // Small trick to get the point index to feed the undo method + int i = _curve_ref->add_point(point_pos); + _curve_ref->remove_point(i); + + ur.add_do_method(*_curve_ref, "add_point", point_pos); + ur.add_undo_method(*_curve_ref, "remove_point", i); - push_undo(prev_data); + ur.commit_action(); } void CurveEditor::remove_point(int index) { ERR_FAIL_COND(_curve_ref.is_null()); - Array prev_data = _curve_ref->get_data(); + UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); + ur.create_action(TTR("Remove Curve Point")); + + Curve::Point p = _curve_ref->get_point(index); - _curve_ref->remove_point(index); + ur.add_do_method(*_curve_ref, "remove_point", index); + ur.add_undo_method(*_curve_ref, "add_point", p.pos, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode); if (index == _selected_point) set_selected_point(-1); - push_undo(prev_data); + ur.commit_action(); } void CurveEditor::toggle_linear(TangentIndex tangent) { ERR_FAIL_COND(_curve_ref.is_null()); - Array prev_data = _curve_ref->get_data(); + UndoRedo &ur = *EditorNode::get_singleton()->get_undo_redo(); + ur.create_action(TTR("Toggle Curve Linear Tangent")); if (tangent == TANGENT_NONE) tangent = _selected_tangent; if (tangent == TANGENT_LEFT) { + bool is_linear = _curve_ref->get_point_left_mode(_selected_point) == Curve::TANGENT_LINEAR; - _curve_ref->set_point_left_mode(_selected_point, is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR); + + Curve::TangentMode prev_mode = _curve_ref->get_point_left_mode(_selected_point); + Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR; + + ur.add_do_method(*_curve_ref, "set_point_left_mode", _selected_point, mode); + ur.add_undo_method(*_curve_ref, "set_point_left_mode", _selected_point, prev_mode); + } else { + bool is_linear = _curve_ref->get_point_right_mode(_selected_point) == Curve::TANGENT_LINEAR; - _curve_ref->set_point_right_mode(_selected_point, is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR); + + Curve::TangentMode prev_mode = _curve_ref->get_point_right_mode(_selected_point); + Curve::TangentMode mode = is_linear ? Curve::TANGENT_FREE : Curve::TANGENT_LINEAR; + + ur.add_do_method(*_curve_ref, "set_point_right_mode", _selected_point, mode); + ur.add_undo_method(*_curve_ref, "set_point_right_mode", _selected_point, prev_mode); } - push_undo(prev_data); + ur.commit_action(); } void CurveEditor::set_selected_point(int index) { @@ -456,20 +494,6 @@ void CurveEditor::set_hover_point_index(int index) { } } -void CurveEditor::push_undo(Array previous_curve_data) { - UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo(); - - ur->create_action(TTR("Modify Curve")); - ur->add_do_method(*_curve_ref, "_set_data", _curve_ref->get_data()); - ur->add_undo_method(*_curve_ref, "_set_data", previous_curve_data); - - // This boolean is to prevent commit_action from executing the do method, - // because at this point it's already done, there is no point in doing it twice - _curve_ref->_disable_set_data = true; - ur->commit_action(); - _curve_ref->_disable_set_data = false; -} - void CurveEditor::update_view_transform() { Vector2 control_size = get_size(); const real_t margin = 24; diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index 39d9b84d88..a4952dfb28 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -88,7 +88,6 @@ private: void toggle_linear(TangentIndex tangent = TANGENT_NONE); void set_selected_point(int index); void set_hover_point_index(int index); - void push_undo(Array previous_curve_data); void update_view_transform(); Vector2 get_tangent_view_pos(int i, TangentIndex tangent) const; @@ -108,7 +107,6 @@ private: Array _undo_data; bool _has_undo_data; - bool _undo_no_commit; Vector2 _context_click_pos; int _selected_point; diff --git a/methods.py b/methods.py index 2f9d45897e..4d3d5ae343 100644 --- a/methods.py +++ b/methods.py @@ -1513,23 +1513,26 @@ def split_lib(self, libname): def save_active_platforms(apnames, ap): for x in ap: - pth = x + "/logo.png" -# print("open path: "+pth) - pngf = open(pth, "rb") - b = pngf.read(1) - str = " /* AUTOGENERATED FILE, DO NOT EDIT */ \n" - str += " static const unsigned char _" + x[9:] + "_logo[]={" - while(len(b) == 1): - str += hex(ord(b)) - b = pngf.read(1) - if (len(b) == 1): - str += "," - - str += "};\n" + names = ['logo'] + if os.path.isfile(x + "/run_icon.png"): + names.append('run_icon') - wf = x + "/logo.gen.h" - logow = open(wf, "wb") - logow.write(str) + for name in names: + pngf = open(x + "/" + name + ".png", "rb") + b = pngf.read(1) + str = " /* AUTOGENERATED FILE, DO NOT EDIT */ \n" + str += " static const unsigned char _" + x[9:] + "_" + name + "[]={" + while(len(b) == 1): + str += hex(ord(b)) + b = pngf.read(1) + if (len(b) == 1): + str += "," + + str += "};\n" + + wf = x + "/" + name + ".gen.h" + pngw = open(wf, "wb") + pngw.write(str) def no_verbose(sys, env): diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index d6ed234669..a72e8aa90e 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -37,6 +37,7 @@ #include "os/file_access.h" #include "os/os.h" #include "platform/android/logo.gen.h" +#include "platform/android/run_icon.gen.h" #include "version.h" #include <string.h> #if 0 @@ -2042,6 +2043,7 @@ class EditorExportAndroid : public EditorExportPlatform { GDCLASS(EditorExportAndroid, EditorExportPlatform) Ref<ImageTexture> logo; + Ref<ImageTexture> run_icon; struct Device { @@ -3036,6 +3038,10 @@ public: return OK; } + virtual Ref<Texture> get_run_icon() const { + return run_icon; + } + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String(); @@ -3524,9 +3530,13 @@ public: EditorExportAndroid() { Ref<Image> img = memnew(Image(_android_logo)); - logo = Ref<ImageTexture>(memnew(ImageTexture)); + logo.instance(); logo->create_from_image(img); + img = Ref<Image>(memnew(Image(_android_run_icon))); + run_icon.instance(); + run_icon->create_from_image(img); + device_lock = Mutex::create(); device_thread = Thread::create(_device_poll_thread, this); devices_changed = true; diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png Binary files differnew file mode 100644 index 0000000000..e53f8e9da5 --- /dev/null +++ b/platform/android/run_icon.png diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 8b04deabd7..4bdfdae39e 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -31,6 +31,7 @@ #include "editor_export.h" #include "io/zip_io.h" #include "platform/javascript/logo.gen.h" +#include "platform/javascript/run_icon.gen.h" #define EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE "webassembly_release.zip" #define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip" @@ -42,6 +43,8 @@ class EditorExportPlatformJavaScript : public EditorExportPlatform { GDCLASS(EditorExportPlatformJavaScript, EditorExportPlatform) Ref<ImageTexture> logo; + Ref<ImageTexture> run_icon; + bool runnable_when_last_polled; void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug); void _fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size); @@ -64,10 +67,12 @@ public: virtual String get_binary_extension() const; virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual int get_device_count() const { return 1; } + virtual bool poll_devices(); + virtual int get_device_count() const; virtual String get_device_name(int p_device) const { return TTR("Run in Browser"); } virtual String get_device_info(int p_device) const { return TTR("Run exported HTML in the system's default browser."); } virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags); + virtual Ref<Texture> get_run_icon() const; EditorExportPlatformJavaScript(); }; @@ -303,6 +308,29 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese return OK; } +bool EditorExportPlatformJavaScript::poll_devices() { + + Ref<EditorExportPreset> preset; + + for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { + + Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i); + if (ep->is_runnable() && ep->get_platform() == this) { + preset = ep; + break; + } + } + + bool prev = runnable_when_last_polled; + runnable_when_last_polled = preset.is_valid(); + return runnable_when_last_polled != prev; +} + +int EditorExportPlatformJavaScript::get_device_count() const { + + return runnable_when_last_polled; +} + Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp_export.html"; @@ -314,11 +342,22 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese return OK; } +Ref<Texture> EditorExportPlatformJavaScript::get_run_icon() const { + + return run_icon; +} + EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { Ref<Image> img = memnew(Image(_javascript_logo)); logo.instance(); logo->create_from_image(img); + + img = Ref<Image>(memnew(Image(_javascript_run_icon))); + run_icon.instance(); + run_icon->create_from_image(img); + + runnable_when_last_polled = false; } void register_javascript_exporter() { diff --git a/platform/javascript/run_icon.png b/platform/javascript/run_icon.png Binary files differnew file mode 100644 index 0000000000..dedee6f479 --- /dev/null +++ b/platform/javascript/run_icon.png diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index 0cd41f557a..bc6d0230a0 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -387,12 +387,9 @@ Curve::Curve() { _baked_cache_dirty = false; _min_value = 0; _max_value = 1; -#ifdef TOOLS_ENABLED - _disable_set_data = false; -#endif } -int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent) { +int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) { // Add a point and preserve order // Curve bounds is in 0..1 @@ -404,7 +401,7 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent) { int ret = -1; if (_points.size() == 0) { - _points.push_back(Point(p_pos, left_tangent, right_tangent)); + _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); ret = 0; } else if (_points.size() == 1) { @@ -413,10 +410,10 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent) { real_t diff = p_pos.x - _points[0].pos.x; if (diff > 0) { - _points.push_back(Point(p_pos, left_tangent, right_tangent)); + _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); ret = 1; } else { - _points.insert(0, Point(p_pos, left_tangent, right_tangent)); + _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); ret = 0; } @@ -435,16 +432,18 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent) { if (i == 0 && p_pos.x < _points[0].pos.x) { // Insert before anything else - _points.insert(0, Point(p_pos, left_tangent, right_tangent)); + _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); ret = 0; } else { // Insert between i and i+1 ++i; - _points.insert(i, Point(p_pos, left_tangent, right_tangent)); + _points.insert(i, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode)); ret = i; } } + update_auto_tangents(ret); + mark_dirty(); return ret; @@ -593,6 +592,11 @@ Vector2 Curve::get_point_pos(int p_index) const { return _points[p_index].pos; } +Curve::Point Curve::get_point(int p_index) const { + ERR_FAIL_INDEX_V(p_index, _points.size(), Point()); + return _points[p_index]; +} + void Curve::update_auto_tangents(int i) { Point &p = _points[i]; @@ -699,33 +703,32 @@ void Curve::mark_dirty() { Array Curve::get_data() const { Array output; - output.resize(_points.size() * 3); + const unsigned int ELEMS = 5; + output.resize(_points.size() * ELEMS); for (int j = 0; j < _points.size(); ++j) { const Point p = _points[j]; - int i = j * 3; + int i = j * ELEMS; output[i] = p.pos; output[i + 1] = p.left_tangent; output[i + 2] = p.right_tangent; + output[i + 3] = p.left_mode; + output[i + 4] = p.right_mode; } return output; } void Curve::set_data(Array input) { - ERR_FAIL_COND(input.size() % 3 != 0); - -#ifdef TOOLS_ENABLED - if (_disable_set_data) - return; -#endif + const unsigned int ELEMS = 5; + ERR_FAIL_COND(input.size() % ELEMS != 0); _points.clear(); // Validate input - for (int i = 0; i < input.size(); i += 3) { + for (int i = 0; i < input.size(); i += ELEMS) { ERR_FAIL_COND(input[i].get_type() != Variant::VECTOR2); ERR_FAIL_COND(input[i + 1].get_type() != Variant::REAL); ERR_FAIL_COND(input[i + 2].get_type() != Variant::REAL); @@ -739,12 +742,12 @@ void Curve::set_data(Array input) { ERR_FAIL_COND(right_mode < 0 || right_mode >= TANGENT_MODE_COUNT); } - _points.resize(input.size() / 3); + _points.resize(input.size() / ELEMS); for (int j = 0; j < _points.size(); ++j) { Point &p = _points[j]; - int i = j * 3; + int i = j * ELEMS; p.pos = input[i]; p.left_tangent = input[i + 1]; @@ -822,7 +825,8 @@ real_t Curve::interpolate_baked(real_t offset) { void Curve::_bind_methods() { - ClassDB::bind_method(D_METHOD("add_point", "pos", "left_tangent", "right_tangent"), &Curve::add_point, DEFVAL(0), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_point", "pos", "left_tangent", "right_tangent", "left_mode", "right_mode"), + &Curve::add_point, DEFVAL(0), DEFVAL(0), DEFVAL(TANGENT_FREE), DEFVAL(TANGENT_FREE)); ClassDB::bind_method(D_METHOD("remove_point", "index"), &Curve::remove_point); ClassDB::bind_method(D_METHOD("clear_points"), &Curve::clear_points); ClassDB::bind_method(D_METHOD("get_point_pos", "index"), &Curve::get_point_pos); diff --git a/scene/resources/curve.h b/scene/resources/curve.h index d45f9e202f..83a4357bfb 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -91,10 +91,6 @@ public: static const char *SIGNAL_RANGE_CHANGED; -#ifdef TOOLS_ENABLED - bool _disable_set_data; -#endif - enum TangentMode { TANGENT_FREE = 0, TANGENT_LINEAR, @@ -115,12 +111,17 @@ public: right_mode = TANGENT_FREE; } - Point(Vector2 p, real_t left = 0, real_t right = 0) { - pos = p; - left_tangent = left; - right_tangent = right; - left_mode = TANGENT_FREE; - right_mode = TANGENT_FREE; + Point(Vector2 p_pos, + real_t p_left = 0, + real_t p_right = 0, + TangentMode p_left_mode = TANGENT_FREE, + TangentMode p_right_mode = TANGENT_FREE) { + + pos = p_pos; + left_tangent = p_left; + right_tangent = p_right; + left_mode = p_left_mode; + right_mode = p_right_mode; } }; @@ -128,7 +129,12 @@ public: int get_point_count() const { return _points.size(); } - int add_point(Vector2 p_pos, real_t left_tangent = 0, real_t right_tangent = 0); + int add_point(Vector2 p_pos, + real_t left_tangent = 0, + real_t right_tangent = 0, + TangentMode left_mode = TANGENT_FREE, + TangentMode right_mode = TANGENT_FREE); + void remove_point(int p_index); void clear_points(); @@ -138,6 +144,8 @@ public: int set_point_offset(int p_index, float offset); Vector2 get_point_pos(int p_index) const; + Point get_point(int p_index) const; + float get_min_value() const { return _min_value; } void set_min_value(float p_min); |