From 53541c69d48444bf8a502b35dcd4370c30058fb6 Mon Sep 17 00:00:00 2001 From: Guilherme Felipe Date: Wed, 13 May 2015 23:19:15 -0300 Subject: Fix for scroll_to_line and search functions, fix #1897 The function scroll_to_line(0) should return ERR_FAIL_INDEX because the first line is 1. --- scene/gui/rich_text_label.cpp | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 6b2e5aea78..bf719e671a 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1486,10 +1486,10 @@ Error RichTextLabel::append_bbcode(const String& p_bbcode) { void RichTextLabel::scroll_to_line(int p_line) { + p_line -= 1; ERR_FAIL_INDEX(p_line,lines.size()); _validate_line_caches(); - vscroll->set_val(lines[p_line].height_accum_cache); - + vscroll->set_val(lines[p_line].height_accum_cache-lines[p_line].height_cache); } @@ -1552,27 +1552,23 @@ bool RichTextLabel::search(const String& p_string,bool p_from_selection) { it=_get_next_item(it); } - if (!it) - line=lines.size()-1; } - scroll_to_line(line-2); + if (line > 1) { + line-=1; + } + + scroll_to_line(line); return true; } - } else if (it->type==ITEM_NEWLINE) { - - line=static_cast(it)->line; } - it=_get_next_item(it); charidx=0; } - - return false; } -- cgit v1.2.3 From 4a56f72f5be6cd34c96a082e3697f4eecd744e75 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sun, 24 May 2015 23:22:51 +0300 Subject: Haiku: Initial support. --- platform/haiku/SCsub | 10 ++++++++++ platform/haiku/detect.py | 42 +++++++++++++++++++++++++++++++++++++++ platform/haiku/godot_haiku.cpp | 19 ++++++++++++++++++ platform/haiku/logo.png | Bin 0 -> 2055 bytes platform/haiku/os_haiku.cpp | 0 platform/haiku/os_haiku.h | 42 +++++++++++++++++++++++++++++++++++++++ platform/haiku/platform_config.h | 1 + 7 files changed, 114 insertions(+) create mode 100644 platform/haiku/SCsub create mode 100644 platform/haiku/detect.py create mode 100644 platform/haiku/godot_haiku.cpp create mode 100644 platform/haiku/logo.png create mode 100644 platform/haiku/os_haiku.cpp create mode 100644 platform/haiku/os_haiku.h create mode 100644 platform/haiku/platform_config.h diff --git a/platform/haiku/SCsub b/platform/haiku/SCsub new file mode 100644 index 0000000000..8ae489cf54 --- /dev/null +++ b/platform/haiku/SCsub @@ -0,0 +1,10 @@ +Import('env') + +common_haiku = [ + 'os_haiku.cpp' +] + +env.Program( + '#bin/godot', + ['godot_haiku.cpp'] + common_haiku +) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py new file mode 100644 index 0000000000..992c73ee79 --- /dev/null +++ b/platform/haiku/detect.py @@ -0,0 +1,42 @@ +import os +import sys + +def is_active(): + return True + +def get_name(): + return "Haiku" + +def can_build(): + if (os.name != "posix"): + return False + + if (sys.platform == "darwin"): + return False + + return True + +def get_opts(): + return [] + +def get_flags(): + return [ + ('builtin_zlib', 'no') + ] + +def configure(env): + is64=sys.maxsize > 2**32 + + if (env["bits"]=="default"): + if (is64): + env["bits"]="64" + else: + env["bits"]="32" + + env.Append(CPPPATH = ['#platform/haiku']) + env["CC"] = "gcc-x86" + env["CXX"] = "g++-x86" + env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) + + env.Append(CPPFLAGS = ['-DUNIX_ENABLED']) + #env.Append(LIBS = ['be']) diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp new file mode 100644 index 0000000000..b4e5e50891 --- /dev/null +++ b/platform/haiku/godot_haiku.cpp @@ -0,0 +1,19 @@ +#include "main/main.h" +#include "os_haiku.h" + +int main(int argc, char* argv[]) { + OS_Haiku os; + + Error error = Main::setup(argv[0], argc-1, &argv[1]); + if (error != OK) { + return 255; + } + + if (Main::start()) { + os.run(); + } + + Main::cleanup(); + + return os.get_exit_code(); +} diff --git a/platform/haiku/logo.png b/platform/haiku/logo.png new file mode 100644 index 0000000000..c40214d6de Binary files /dev/null and b/platform/haiku/logo.png differ diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h new file mode 100644 index 0000000000..ee1283f018 --- /dev/null +++ b/platform/haiku/os_haiku.h @@ -0,0 +1,42 @@ +#ifndef OS_HAIKU_H +#define OS_HAIKU_H + +#include "drivers/unix/os_unix.h" + + +class OS_Haiku : public OS_Unix { +private: + virtual void delete_main_loop(); + +protected: + virtual int get_video_driver_count() const; + virtual const char* get_video_driver_name(int p_driver) const; + virtual VideoMode get_default_video_mode() const; + + virtual void initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver); + virtual void finalize(); + + virtual void set_main_loop(MainLoop* p_main_loop); + +public: + OS_Haiku(); + void run(); + + virtual String get_name(); + + virtual MainLoop *get_main_loop() const; + virtual bool can_draw() const; + + virtual Point2 get_mouse_pos() const; + virtual int get_mouse_button_state() const; + virtual void set_cursor_shape(CursorShape p_shape); + + virtual void set_window_title(const String& p_title); + virtual Size2 get_window_size() const; + + virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0); + virtual VideoMode get_video_mode(int p_screen=0) const; + virtual void get_fullscreen_mode_list(List *p_list, int p_screen=0) const; +}; + +#endif diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h new file mode 100644 index 0000000000..dad24432a5 --- /dev/null +++ b/platform/haiku/platform_config.h @@ -0,0 +1 @@ +#include -- cgit v1.2.3 From 4e07a2dea8c94337702d35d0d02d4b7234f86e29 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Mon, 25 May 2015 03:49:24 +0300 Subject: Haiku: fix building with UNIX_ENABLED. --- drivers/unix/packet_peer_udp_posix.cpp | 6 +++++- drivers/unix/stream_peer_tcp_posix.cpp | 9 +++++++-- drivers/unix/tcp_server_posix.cpp | 6 +++++- platform/haiku/detect.py | 6 ++++-- platform/haiku/os_haiku.cpp | 5 +++++ 5 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp index 26a0b29228..94b4c35923 100644 --- a/drivers/unix/packet_peer_udp_posix.cpp +++ b/drivers/unix/packet_peer_udp_posix.cpp @@ -13,7 +13,11 @@ #include #ifndef NO_FCNTL -#include + #ifdef __HAIKU__ + #include + #else + #include + #endif #else #include #endif diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 2301d8b6c4..2db7d9f6ec 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -39,7 +39,11 @@ #include #include #ifndef NO_FCNTL -#include + #ifdef __HAIKU__ + #include + #else + #include + #endif #else #include #endif @@ -202,7 +206,8 @@ Error StreamPeerTCPPosix::write(const uint8_t* p_data,int p_bytes, int &r_sent, while (data_to_send) { - int sent_amount = send(sockfd, offset, data_to_send, MSG_NOSIGNAL); + // TODO: handle MSG_NOSIGNAL on __HAIKU__ + int sent_amount = send(sockfd, offset, data_to_send, 0); //printf("Sent TCP data of %d bytes, errno %d\n", sent_amount, errno); if (sent_amount == -1) { diff --git a/drivers/unix/tcp_server_posix.cpp b/drivers/unix/tcp_server_posix.cpp index 4f9ee62cde..aaca0fe0d8 100644 --- a/drivers/unix/tcp_server_posix.cpp +++ b/drivers/unix/tcp_server_posix.cpp @@ -41,7 +41,11 @@ #include #include #ifndef NO_FCNTL -#include + #ifdef __HAIKU__ + #include + #else + #include + #endif #else #include #endif diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 992c73ee79..5dad2af033 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -34,9 +34,11 @@ def configure(env): env["bits"]="32" env.Append(CPPPATH = ['#platform/haiku']) + + # TODO: add clang and try gcc2 too env["CC"] = "gcc-x86" env["CXX"] = "g++-x86" - env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) + env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) env.Append(CPPFLAGS = ['-DUNIX_ENABLED']) - #env.Append(LIBS = ['be']) + env.Append(LIBS = ['be']) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index e69de29bb2..8841306b7a 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -0,0 +1,5 @@ +#include "os_haiku.h" + +String OS_Haiku::get_name() { + return "Haiku"; +} -- cgit v1.2.3 From 826f8af1ef3311ddcc0fab27629f7a5fcfa1b024 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Mon, 25 May 2015 06:02:55 +0300 Subject: Haiku: link with the haiku libs, stub the OS_Haiku class. --- drivers/unix/stream_peer_tcp_posix.cpp | 8 +++- platform/haiku/detect.py | 2 +- platform/haiku/os_haiku.cpp | 76 ++++++++++++++++++++++++++++++++++ platform/haiku/os_haiku.h | 3 +- 4 files changed, 85 insertions(+), 4 deletions(-) diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 2db7d9f6ec..f65eb694d6 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -206,8 +206,12 @@ Error StreamPeerTCPPosix::write(const uint8_t* p_data,int p_bytes, int &r_sent, while (data_to_send) { - // TODO: handle MSG_NOSIGNAL on __HAIKU__ - int sent_amount = send(sockfd, offset, data_to_send, 0); + // TODO: haiku does not have MSG_NOSIGNAL +#ifdef __HAIKU__ + int sent_amount = send(sockfd, offset, data_to_send, 0); +#else + int sent_amount = send(sockfd, offset, data_to_send, MSG_NOSIGNAL); +#endif //printf("Sent TCP data of %d bytes, errno %d\n", sent_amount, errno); if (sent_amount == -1) { diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 5dad2af033..b443469d8d 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -41,4 +41,4 @@ def configure(env): env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) env.Append(CPPFLAGS = ['-DUNIX_ENABLED']) - env.Append(LIBS = ['be']) + env.Append(LIBS = ['be', 'z', 'network', 'bnetapi']) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 8841306b7a..4d45bb3333 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -1,5 +1,81 @@ #include "os_haiku.h" +OS_Haiku::OS_Haiku() { + +}; + +void OS_Haiku::run() { + +} + String OS_Haiku::get_name() { return "Haiku"; } + +void OS_Haiku::delete_main_loop() { + +} + +int OS_Haiku::get_video_driver_count() const { + +} + +const char* OS_Haiku::get_video_driver_name(int p_driver) const { + +} + +OS::VideoMode OS_Haiku::get_default_video_mode() const { + +} + +void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver) { + +} + +void OS_Haiku::finalize() { + +} + +void OS_Haiku::set_main_loop(MainLoop* p_main_loop) { + +} + +MainLoop* OS_Haiku::get_main_loop() const { + +} + +bool OS_Haiku::can_draw() const { + +} + +Point2 OS_Haiku::get_mouse_pos() const { + +} + +int OS_Haiku::get_mouse_button_state() const { + +} + +void OS_Haiku::set_cursor_shape(CursorShape p_shape) { + +} + +void OS_Haiku::set_window_title(const String& p_title) { + +} + +Size2 OS_Haiku::get_window_size() const { + +} + +void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) { + +} + +OS::VideoMode OS_Haiku::get_video_mode(int p_screen) const { + +} + +void OS_Haiku::get_fullscreen_mode_list(List *p_list, int p_screen) const { + +} diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index ee1283f018..7e3cf84579 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -1,6 +1,7 @@ #ifndef OS_HAIKU_H #define OS_HAIKU_H +#include "os/os.h" #include "drivers/unix/os_unix.h" @@ -24,7 +25,7 @@ public: virtual String get_name(); - virtual MainLoop *get_main_loop() const; + virtual MainLoop* get_main_loop() const; virtual bool can_draw() const; virtual Point2 get_mouse_pos() const; -- cgit v1.2.3 From a5533270436e51c660d2c196e2a6a8f9e21d6420 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Mon, 25 May 2015 06:34:16 +0300 Subject: Haiku: some small fixes --- drivers/unix/stream_peer_tcp_posix.cpp | 5 ++--- platform/haiku/os_haiku.cpp | 4 ++++ platform/haiku/os_haiku.h | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index f65eb694d6..6e19647933 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -206,11 +206,10 @@ Error StreamPeerTCPPosix::write(const uint8_t* p_data,int p_bytes, int &r_sent, while (data_to_send) { - // TODO: haiku does not have MSG_NOSIGNAL #ifdef __HAIKU__ - int sent_amount = send(sockfd, offset, data_to_send, 0); + int sent_amount = send(sockfd, offset, data_to_send, 0); #else - int sent_amount = send(sockfd, offset, data_to_send, MSG_NOSIGNAL); + int sent_amount = send(sockfd, offset, data_to_send, MSG_NOSIGNAL); #endif //printf("Sent TCP data of %d bytes, errno %d\n", sent_amount, errno); diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 4d45bb3333..7c207f265b 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -79,3 +79,7 @@ OS::VideoMode OS_Haiku::get_video_mode(int p_screen) const { void OS_Haiku::get_fullscreen_mode_list(List *p_list, int p_screen) const { } + +String OS_Haiku::get_executable_path() const { + return OS::get_executable_path(); +} diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 7e3cf84579..8740a738cc 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -1,7 +1,6 @@ #ifndef OS_HAIKU_H #define OS_HAIKU_H -#include "os/os.h" #include "drivers/unix/os_unix.h" @@ -38,6 +37,7 @@ public: virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0); virtual VideoMode get_video_mode(int p_screen=0) const; virtual void get_fullscreen_mode_list(List *p_list, int p_screen=0) const; + virtual String get_executable_path() const; }; #endif -- cgit v1.2.3 From 8dd674d6399b5543f589d3b770c97209e3e31c3b Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Thu, 28 May 2015 00:59:41 +0300 Subject: Haiku: enable debug support --- platform/haiku/detect.py | 12 +++++++++++- platform/haiku/platform_config.h | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index b443469d8d..0c4d091824 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -39,6 +39,16 @@ def configure(env): env["CC"] = "gcc-x86" env["CXX"] = "g++-x86" - env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) + if (env["target"]=="release"): + if (env["debug_release"]=="yes"): + env.Append(CCFLAGS=['-g2','-fomit-frame-pointer']) + else: + env.Append(CCFLAGS=['-O2','-ffast-math','-fomit-frame-pointer']) + elif (env["target"]=="release_debug"): + env.Append(CCFLAGS=['-O2','-ffast-math','-DDEBUG_ENABLED']) + elif (env["target"]=="debug"): + env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED']) + + #env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) env.Append(CPPFLAGS = ['-DUNIX_ENABLED']) env.Append(LIBS = ['be', 'z', 'network', 'bnetapi']) diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h index dad24432a5..d37873ca8b 100644 --- a/platform/haiku/platform_config.h +++ b/platform/haiku/platform_config.h @@ -1 +1,4 @@ #include + +// for ifaddrs.h needed in drivers/unix/ip_unix.cpp +#define _BSD_SOURCE 1 -- cgit v1.2.3 From 513d509783678d1a6c9fd47d7e2e822d886f2c84 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Thu, 28 May 2015 03:42:40 +0300 Subject: Haiku: enable building with GLES --- platform/haiku/detect.py | 5 +++-- platform/haiku/os_haiku.cpp | 46 +++++++++++++++++++++++++++++++++------- platform/haiku/os_haiku.h | 7 +++++- platform/haiku/platform_config.h | 2 ++ 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 0c4d091824..bb123c6aa0 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -49,6 +49,7 @@ def configure(env): elif (env["target"]=="debug"): env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED']) - #env.Append(CPPFLAGS = ['-DDEBUG_METHODS_ENABLED']) - env.Append(CPPFLAGS = ['-DUNIX_ENABLED']) + #env.Append(CCFLAGS=['-DFREETYPE_ENABLED']) + env.Append(CPPFLAGS = ['-DOPENGL_ENABLED', '-DGLEW_ENABLED']) + env.Append(CPPFLAGS = ['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL']) env.Append(LIBS = ['be', 'z', 'network', 'bnetapi']) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 7c207f265b..103b1ac748 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -1,3 +1,5 @@ +#include "servers/visual/visual_server_raster.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "os_haiku.h" OS_Haiku::OS_Haiku() { @@ -5,17 +7,13 @@ OS_Haiku::OS_Haiku() { }; void OS_Haiku::run() { - + } String OS_Haiku::get_name() { return "Haiku"; } -void OS_Haiku::delete_main_loop() { - -} - int OS_Haiku::get_video_driver_count() const { } @@ -29,19 +27,51 @@ OS::VideoMode OS_Haiku::get_default_video_mode() const { } void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver) { - + main_loop = NULL; + +#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + //context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); + //context_gl->initialize(); + + rasterizer = memnew(RasterizerGLES2); +#endif + + visual_server = memnew(VisualServerRaster(rasterizer)); + + if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); + } } void OS_Haiku::finalize() { - + if (main_loop) { + memdelete(main_loop); + } + + main_loop = NULL; + + visual_server->finish(); + memdelete(visual_server); + memdelete(rasterizer); } void OS_Haiku::set_main_loop(MainLoop* p_main_loop) { + main_loop = p_main_loop; + // TODO: enable + //input->set_main_loop(p_main_loop); } MainLoop* OS_Haiku::get_main_loop() const { - + return main_loop; +} + +void OS_Haiku::delete_main_loop() { + if (main_loop) { + memdelete(main_loop); + } + + main_loop = NULL; } bool OS_Haiku::can_draw() const { diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 8740a738cc..67faff5e96 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -2,10 +2,15 @@ #define OS_HAIKU_H #include "drivers/unix/os_unix.h" - +#include "servers/visual_server.h" +#include "servers/visual/rasterizer.h" class OS_Haiku : public OS_Unix { private: + MainLoop* main_loop; + Rasterizer* rasterizer; + VisualServer* visual_server; + virtual void delete_main_loop(); protected: diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h index d37873ca8b..b63b600fc1 100644 --- a/platform/haiku/platform_config.h +++ b/platform/haiku/platform_config.h @@ -2,3 +2,5 @@ // for ifaddrs.h needed in drivers/unix/ip_unix.cpp #define _BSD_SOURCE 1 + +#define GLES2_INCLUDE_H "gl_context/glew.h" -- cgit v1.2.3 From db459fba1db908b21d6ea3e99c6e75d65c6cc6b0 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Fri, 29 May 2015 23:36:48 +0300 Subject: Haiku: fix build, link with libGL and libGLEW --- platform/haiku/detect.py | 9 +++++++-- platform/haiku/os_haiku.cpp | 1 + platform/haiku/platform_config.h | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index bb123c6aa0..2c15720a92 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -50,6 +50,11 @@ def configure(env): env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED']) #env.Append(CCFLAGS=['-DFREETYPE_ENABLED']) - env.Append(CPPFLAGS = ['-DOPENGL_ENABLED', '-DGLEW_ENABLED']) + env.Append(CPPFLAGS = ['-DOPENGL_ENABLED']) env.Append(CPPFLAGS = ['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL']) - env.Append(LIBS = ['be', 'z', 'network', 'bnetapi']) + env.Append(LIBS = ['be', 'GL', 'GLEW', 'z', 'network', 'bnetapi']) + + import methods + env.Append(BUILDERS = {'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl')}) + env.Append(BUILDERS = {'GLSL' : env.Builder(action = methods.build_glsl_headers, suffix = 'glsl.h',src_suffix = '.glsl')}) + env.Append(BUILDERS = {'GLSL120GLES' : env.Builder(action = methods.build_gles2_headers, suffix = 'glsl.h',src_suffix = '.glsl')}) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 103b1ac748..dc3419b09e 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -1,4 +1,5 @@ #include "servers/visual/visual_server_raster.h" +#include "servers/visual/visual_server_wrap_mt.h" #include "drivers/gles2/rasterizer_gles2.h" #include "os_haiku.h" diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h index b63b600fc1..691bdbdb9c 100644 --- a/platform/haiku/platform_config.h +++ b/platform/haiku/platform_config.h @@ -3,4 +3,4 @@ // for ifaddrs.h needed in drivers/unix/ip_unix.cpp #define _BSD_SOURCE 1 -#define GLES2_INCLUDE_H "gl_context/glew.h" +#define GLES2_INCLUDE_H -- cgit v1.2.3 From 8130707e018757d9270d8b3d94241eaecc82b896 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sat, 30 May 2015 00:57:07 +0300 Subject: Haiku: start implementing the os-dependant stuff --- platform/haiku/os_haiku.cpp | 29 ++++++++++++++++------------- platform/haiku/os_haiku.h | 1 + 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index dc3419b09e..fb06413478 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -8,7 +8,7 @@ OS_Haiku::OS_Haiku() { }; void OS_Haiku::run() { - + ERR_PRINT("run() NOT IMPLEMENTED"); } String OS_Haiku::get_name() { @@ -16,19 +16,20 @@ String OS_Haiku::get_name() { } int OS_Haiku::get_video_driver_count() const { - + return 1; } const char* OS_Haiku::get_video_driver_name(int p_driver) const { - + return "GLES2"; } OS::VideoMode OS_Haiku::get_default_video_mode() const { - + return OS::VideoMode(800, 600, false); } void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_audio_driver) { main_loop = NULL; + current_video_mode = p_desired; #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) //context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); @@ -42,6 +43,8 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } + + visual_server->init(); } void OS_Haiku::finalize() { @@ -76,39 +79,39 @@ void OS_Haiku::delete_main_loop() { } bool OS_Haiku::can_draw() const { - + ERR_PRINT("can_draw() NOT IMPLEMENTED"); } Point2 OS_Haiku::get_mouse_pos() const { - + ERR_PRINT("get_mouse_pos() NOT IMPLEMENTED"); } int OS_Haiku::get_mouse_button_state() const { - + ERR_PRINT("get_mouse_button_state() NOT IMPLEMENTED"); } void OS_Haiku::set_cursor_shape(CursorShape p_shape) { - + ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED"); } void OS_Haiku::set_window_title(const String& p_title) { - + ERR_PRINT("set_window_title() NOT IMPLEMENTED"); } Size2 OS_Haiku::get_window_size() const { - + ERR_PRINT("get_window_size() NOT IMPLEMENTED"); } void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) { - + ERR_PRINT("set_video_mode() NOT IMPLEMENTED"); } OS::VideoMode OS_Haiku::get_video_mode(int p_screen) const { - + return current_video_mode; } void OS_Haiku::get_fullscreen_mode_list(List *p_list, int p_screen) const { - + ERR_PRINT("get_fullscreen_mode_list() NOT IMPLEMENTED"); } String OS_Haiku::get_executable_path() const { diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 67faff5e96..dfe559c969 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -10,6 +10,7 @@ private: MainLoop* main_loop; Rasterizer* rasterizer; VisualServer* visual_server; + VideoMode current_video_mode; virtual void delete_main_loop(); -- cgit v1.2.3 From 310f061a4a9ef2325d40cd5f194fe22d54094a31 Mon Sep 17 00:00:00 2001 From: Rodolfo Ribeiro Gomes Date: Mon, 8 Jun 2015 23:19:52 -0300 Subject: Small fix for Import Game dialog labels --- tools/editor/project_manager.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/editor/project_manager.cpp b/tools/editor/project_manager.cpp index 00956919b7..43e8d48dd9 100644 --- a/tools/editor/project_manager.cpp +++ b/tools/editor/project_manager.cpp @@ -245,7 +245,8 @@ public: project_name->clear(); if (import_mode) { - set_title("Import Existing Project:"); + set_title("Import Existing Project"); + get_ok()->set_text("Import"); pp->set_text("Project Path: (Must exist)"); pn->set_text("Project Name:"); pn->hide(); @@ -254,7 +255,8 @@ public: popup_centered(Size2(500,125)); } else { - set_title("Create New Project:"); + set_title("Create New Project"); + get_ok()->set_text("Create"); pp->set_text("Project Path:"); pn->set_text("Project Name:"); pn->show(); @@ -313,7 +315,6 @@ public: l->add_color_override("font_color",Color(1,0.4,0.3,0.8)); l->set_align(Label::ALIGN_CENTER); - get_ok()->set_text("Create"); DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); project_path->set_text(d->get_current_dir()); memdelete(d); -- cgit v1.2.3 From f99b72c04f484c39ae728bc175114544a26d7bca Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Wed, 10 Jun 2015 21:18:39 +0300 Subject: Haiku: remove an #ifdef as the platform now supports MSG_NOSIGNAL --- drivers/unix/stream_peer_tcp_posix.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp index 6e19647933..5aa3915893 100644 --- a/drivers/unix/stream_peer_tcp_posix.cpp +++ b/drivers/unix/stream_peer_tcp_posix.cpp @@ -206,11 +206,7 @@ Error StreamPeerTCPPosix::write(const uint8_t* p_data,int p_bytes, int &r_sent, while (data_to_send) { -#ifdef __HAIKU__ - int sent_amount = send(sockfd, offset, data_to_send, 0); -#else int sent_amount = send(sockfd, offset, data_to_send, MSG_NOSIGNAL); -#endif //printf("Sent TCP data of %d bytes, errno %d\n", sent_amount, errno); if (sent_amount == -1) { -- cgit v1.2.3 From 8df3e30abd06ce8d51e6b1ad696aabf97ea9f178 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Thu, 11 Jun 2015 22:57:41 +0300 Subject: Haiku: create a GL context and initialize the audio and physics servers --- drivers/gl_context/glew.c | 2 +- platform/haiku/SCsub | 6 ++- platform/haiku/context_gl_haiku.cpp | 55 ++++++++++++++++++++ platform/haiku/context_gl_haiku.h | 31 ++++++++++++ platform/haiku/detect.py | 3 +- platform/haiku/haiku_application.cpp | 7 +++ platform/haiku/haiku_application.h | 15 ++++++ platform/haiku/haiku_direct_window.cpp | 45 ++++++++++++++++ platform/haiku/haiku_direct_window.h | 27 ++++++++++ platform/haiku/haiku_gl_view.cpp | 54 ++++++++++++++++++++ platform/haiku/haiku_gl_view.h | 27 ++++++++++ platform/haiku/os_haiku.cpp | 93 +++++++++++++++++++++++++++++++--- platform/haiku/os_haiku.h | 30 +++++++++++ 13 files changed, 386 insertions(+), 9 deletions(-) create mode 100644 platform/haiku/context_gl_haiku.cpp create mode 100644 platform/haiku/context_gl_haiku.h create mode 100644 platform/haiku/haiku_application.cpp create mode 100644 platform/haiku/haiku_application.h create mode 100644 platform/haiku/haiku_direct_window.cpp create mode 100644 platform/haiku/haiku_direct_window.h create mode 100644 platform/haiku/haiku_gl_view.cpp create mode 100644 platform/haiku/haiku_gl_view.h diff --git a/drivers/gl_context/glew.c b/drivers/gl_context/glew.c index fc0aa28a72..e38942de4f 100644 --- a/drivers/gl_context/glew.c +++ b/drivers/gl_context/glew.c @@ -1,4 +1,4 @@ -#ifdef GLEW_ENABLED +#ifndef GLEW_ENABLED /* ** The OpenGL Extension Wrangler Library ** Copyright (C) 2002-2008, Milan Ikits diff --git a/platform/haiku/SCsub b/platform/haiku/SCsub index 8ae489cf54..18fa2e2b15 100644 --- a/platform/haiku/SCsub +++ b/platform/haiku/SCsub @@ -1,7 +1,11 @@ Import('env') common_haiku = [ - 'os_haiku.cpp' + 'os_haiku.cpp', + 'context_gl_haiku.cpp', + 'haiku_application.cpp', + 'haiku_direct_window.cpp', + 'haiku_gl_view.cpp' ] env.Program( diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp new file mode 100644 index 0000000000..5c82b187b3 --- /dev/null +++ b/platform/haiku/context_gl_haiku.cpp @@ -0,0 +1,55 @@ +#include "context_gl_haiku.h" + +#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + +ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow** p_window, OS::VideoMode& p_default_video_mode) { + video_mode = p_default_video_mode; + + uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH; + + BRect windowRect; + windowRect.Set(50, 50, 800, 600); + + window = new HaikuDirectWindow(windowRect); + view = new HaikuGLView(window->Bounds(), type); + + *p_window = window; +} + +ContextGL_Haiku::~ContextGL_Haiku() { + delete view; +} + +Error ContextGL_Haiku::initialize() { + window->AddChild(view); + view->LockGL(); + window->SetHaikuGLView(view); + window->InitMessageRunner(); + window->Show(); + + return OK; +} + +void ContextGL_Haiku::release_current() { + ERR_PRINT("release_current() NOT IMPLEMENTED"); +} + +void ContextGL_Haiku::make_current() { + ERR_PRINT("make_current() NOT IMPLEMENTED"); +} + +void ContextGL_Haiku::swap_buffers() { + view->SwapBuffers(); +} + +int ContextGL_Haiku::get_window_width() { + // TODO: implement + return 800; +} + +int ContextGL_Haiku::get_window_height() { + // TODO: implement + return 600; +} + +#endif diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h new file mode 100644 index 0000000000..16efa8f61d --- /dev/null +++ b/platform/haiku/context_gl_haiku.h @@ -0,0 +1,31 @@ +#ifndef CONTEXT_GL_HAIKU_H +#define CONTEXT_GL_HAIKU_H + +#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + +#include "os/os.h" +#include "drivers/gl_context/context_gl.h" + +#include "haiku_direct_window.h" +#include "haiku_gl_view.h" + +class ContextGL_Haiku : public ContextGL { +private: + HaikuGLView* view; + HaikuDirectWindow* window; + OS::VideoMode video_mode; + +public: + ContextGL_Haiku(HaikuDirectWindow** p_window, OS::VideoMode& default_video_mode); + ~ContextGL_Haiku(); + + virtual Error initialize(); + virtual void release_current(); + virtual void make_current(); + virtual void swap_buffers(); + virtual int get_window_width(); + virtual int get_window_height(); +}; + +#endif +#endif diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 2c15720a92..587148838f 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -50,9 +50,10 @@ def configure(env): env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED']) #env.Append(CCFLAGS=['-DFREETYPE_ENABLED']) + env.Append(CPPFLAGS = ['-DGLEW_ENABLED']) env.Append(CPPFLAGS = ['-DOPENGL_ENABLED']) env.Append(CPPFLAGS = ['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL']) - env.Append(LIBS = ['be', 'GL', 'GLEW', 'z', 'network', 'bnetapi']) + env.Append(LIBS = ['be', 'game', 'GL', 'GLEW', 'z', 'network', 'bnetapi']) import methods env.Append(BUILDERS = {'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl')}) diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp new file mode 100644 index 0000000000..56024f605d --- /dev/null +++ b/platform/haiku/haiku_application.cpp @@ -0,0 +1,7 @@ +#include "haiku_application.h" + +HaikuApplication::HaikuApplication() + : BApplication("application/x-vnd.Haiku-GLDirectMode") +{ + +} diff --git a/platform/haiku/haiku_application.h b/platform/haiku/haiku_application.h new file mode 100644 index 0000000000..995a917d62 --- /dev/null +++ b/platform/haiku/haiku_application.h @@ -0,0 +1,15 @@ +#ifndef HAIKU_APPLICATION_H +#define HAIKU_APPLICATION_H + +#include // needed for image_id +#include + +class HaikuApplication : public BApplication +{ +public: + HaikuApplication(); +//private: +// HaikuDirectWindow* window; +}; + +#endif diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp new file mode 100644 index 0000000000..e7f2718278 --- /dev/null +++ b/platform/haiku/haiku_direct_window.cpp @@ -0,0 +1,45 @@ +#include "haiku_direct_window.h" + +HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) + : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, 0) +{ + // TODO: formatting + float minWidth = 0.0f; + float maxWidth = 0.0f; + float minHeight = 0.0f; + float maxHeight = 0.0f; + + GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); + SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight); +} + + +HaikuDirectWindow::~HaikuDirectWindow() +{ + delete update_runner; +} + +void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) { + view = p_view; +} + +void HaikuDirectWindow::InitMessageRunner() { + update_runner = new BMessageRunner(BMessenger(view), + new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */); +} + + +bool HaikuDirectWindow::QuitRequested() +{ + view->EnableDirectMode(false); + be_app->PostMessage(B_QUIT_REQUESTED); + return true; +} + + +void HaikuDirectWindow::DirectConnected(direct_buffer_info *info) +{ + view->DirectConnected(info); + view->EnableDirectMode(true); +} + diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h new file mode 100644 index 0000000000..450ea64296 --- /dev/null +++ b/platform/haiku/haiku_direct_window.h @@ -0,0 +1,27 @@ +#ifndef HAIKU_DIRECT_WINDOW_H +#define HAIKU_DIRECT_WINDOW_H + +#include // needed for image_id +#include + +#include "haiku_gl_view.h" + +#define REDRAW_MSG 'rdrw' + +class HaikuDirectWindow : public BDirectWindow +{ +public: + HaikuDirectWindow(BRect p_frame); + ~HaikuDirectWindow(); + + void SetHaikuGLView(HaikuGLView* p_view); + void InitMessageRunner(); + virtual bool QuitRequested(); + virtual void DirectConnected(direct_buffer_info *info); + +private: + HaikuGLView* view; + BMessageRunner* update_runner; +}; + +#endif diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp new file mode 100644 index 0000000000..61a0120656 --- /dev/null +++ b/platform/haiku/haiku_gl_view.cpp @@ -0,0 +1,54 @@ +#include "haiku_gl_view.h" + +HaikuGLView::HaikuGLView(BRect frame, uint32 type) + : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0) +{ + width = frame.right-frame.left; + height = frame.bottom-frame.top; +} + +void HaikuGLView::AttachedToWindow(void) +{ + LockGL(); + BGLView::AttachedToWindow(); + UnlockGL(); + MakeFocus(); +} + +void HaikuGLView::FrameResized(float newWidth, float newHeight) +{ +} + +void HaikuGLView::gDraw(float rotation) +{ +} + +void HaikuGLView::gReshape(int width, int height) +{ +} + +void HaikuGLView::Render(void) +{ + LockGL(); + SwapBuffers(); + UnlockGL(); +} + +void HaikuGLView::MessageReceived(BMessage * msg) +{ + switch (msg->what) { + case 'rdrw': + Render(); + /* Rotate a bit more */ + rotate++; + break; + + default: + BGLView::MessageReceived(msg); + } +} + +void HaikuGLView::KeyDown(const char *bytes, int32 numBytes) +{ + +} diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h new file mode 100644 index 0000000000..44d05fa27f --- /dev/null +++ b/platform/haiku/haiku_gl_view.h @@ -0,0 +1,27 @@ +#ifndef HAIKU_GL_VIEW_H +#define HAIKU_GL_VIEW_H + +#include // needed for image_id +#include + +class HaikuGLView : public BGLView +{ +public: + HaikuGLView(BRect frame, uint32 type); + virtual void AttachedToWindow(void); + virtual void FrameResized(float newWidth, float newHeight); + virtual void MessageReceived(BMessage * msg); + virtual void KeyDown(const char* bytes, int32 numBytes); + + void Render(void); + +private: + void gDraw(float rotation = 0); + void gReshape(int width, int height); + + float width; + float height; + float rotate; +}; + +#endif diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index fb06413478..bf96cf1716 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -1,14 +1,37 @@ #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" #include "drivers/gles2/rasterizer_gles2.h" +#include "servers/physics/physics_server_sw.h" +#include "main/main.h" + #include "os_haiku.h" + OS_Haiku::OS_Haiku() { - + AudioDriverManagerSW::add_driver(&driver_dummy); }; void OS_Haiku::run() { - ERR_PRINT("run() NOT IMPLEMENTED"); + if (!main_loop) { + return; + } + + main_loop->init(); + + /* + while (true) { + // TODO: process events + + if (Main::iteration() == true) { + break; + } + } + */ + + app->Run(); + delete app; + + main_loop->finish(); } String OS_Haiku::get_name() { @@ -31,20 +54,44 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ main_loop = NULL; current_video_mode = p_desired; + app = new HaikuApplication(); + #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) - //context_gl = memnew( ContextGL_X11( x11_display, x11_window,current_videomode, false ) ); - //context_gl->initialize(); + context_gl = memnew(ContextGL_Haiku(&window, current_video_mode)); + context_gl->initialize(); rasterizer = memnew(RasterizerGLES2); #endif visual_server = memnew(VisualServerRaster(rasterizer)); + ERR_FAIL_COND(!visual_server); + if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } visual_server->init(); + + physics_server = memnew(PhysicsServerSW); + physics_server->init(); + physics_2d_server = memnew(Physics2DServerSW); + physics_2d_server->init(); + + AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); + + if (AudioDriverManagerSW::get_driver(p_audio_driver)->init() != OK) { + ERR_PRINT("Initializing audio failed."); + } + + sample_manager = memnew(SampleManagerMallocSW); + audio_server = memnew(AudioServerSW(sample_manager)); + audio_server->init(); + + spatial_sound_server = memnew(SpatialSoundServerSW); + spatial_sound_server->init(); + spatial_sound_2d_server = memnew(SpatialSound2DServerSW); + spatial_sound_2d_server->init(); } void OS_Haiku::finalize() { @@ -54,9 +101,29 @@ void OS_Haiku::finalize() { main_loop = NULL; + spatial_sound_server->finish(); + memdelete(spatial_sound_server); + + spatial_sound_2d_server->finish(); + memdelete(spatial_sound_2d_server); + + audio_server->finish(); + memdelete(audio_server); + memdelete(sample_manager); + visual_server->finish(); memdelete(visual_server); memdelete(rasterizer); + + physics_server->finish(); + memdelete(physics_server); + + physics_2d_server->finish(); + memdelete(physics_2d_server); + +#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + memdelete(context_gl); +#endif } void OS_Haiku::set_main_loop(MainLoop* p_main_loop) { @@ -78,8 +145,21 @@ void OS_Haiku::delete_main_loop() { main_loop = NULL; } +void OS_Haiku::release_rendering_thread() { + ERR_PRINT("release_rendering_thread() NOT IMPLEMENTED"); +} + +void OS_Haiku::make_rendering_thread() { + ERR_PRINT("make_rendering_thread() NOT IMPLEMENTED"); +} + bool OS_Haiku::can_draw() const { - ERR_PRINT("can_draw() NOT IMPLEMENTED"); + // TODO: implement + return true; +} + +void OS_Haiku::swap_buffers() { + context_gl->swap_buffers(); } Point2 OS_Haiku::get_mouse_pos() const { @@ -95,7 +175,8 @@ void OS_Haiku::set_cursor_shape(CursorShape p_shape) { } void OS_Haiku::set_window_title(const String& p_title) { - ERR_PRINT("set_window_title() NOT IMPLEMENTED"); + //ERR_PRINT("set_window_title() NOT IMPLEMENTED"); + window->SetTitle(p_title.utf8().get_data()); } Size2 OS_Haiku::get_window_size() const { diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index dfe559c969..938983347c 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -4,13 +4,39 @@ #include "drivers/unix/os_unix.h" #include "servers/visual_server.h" #include "servers/visual/rasterizer.h" +#include "servers/physics_server.h" +#include "servers/physics_2d/physics_2d_server_sw.h" +#include "servers/audio/audio_server_sw.h" +#include "servers/audio/sample_manager_sw.h" +#include "servers/spatial_sound/spatial_sound_server_sw.h" +#include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" +#include "servers/audio/audio_driver_dummy.h" + +#include "context_gl_haiku.h" +#include "haiku_application.h" +#include "haiku_direct_window.h" + class OS_Haiku : public OS_Unix { private: + HaikuApplication* app; + HaikuDirectWindow* window; MainLoop* main_loop; Rasterizer* rasterizer; VisualServer* visual_server; VideoMode current_video_mode; + PhysicsServer* physics_server; + Physics2DServer* physics_2d_server; + AudioServerSW* audio_server; + SampleManagerMallocSW* sample_manager; + SpatialSoundServerSW* spatial_sound_server; + SpatialSound2DServerSW* spatial_sound_2d_server; + + AudioDriverDummy driver_dummy; // TODO: use a real driver + +#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) + ContextGL_Haiku* context_gl; +#endif virtual void delete_main_loop(); @@ -31,7 +57,11 @@ public: virtual String get_name(); virtual MainLoop* get_main_loop() const; + virtual bool can_draw() const; + virtual void release_rendering_thread(); + virtual void make_rendering_thread(); + virtual void swap_buffers(); virtual Point2 get_mouse_pos() const; virtual int get_mouse_button_state() const; -- cgit v1.2.3 From 1505d65ac9ec9f44195e961f0089343aabe3de79 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Tue, 16 Jun 2015 21:52:24 +0300 Subject: Haiku: handle mouse movement and click events --- platform/haiku/context_gl_haiku.cpp | 27 ++--- platform/haiku/context_gl_haiku.h | 4 +- platform/haiku/haiku_direct_window.cpp | 177 +++++++++++++++++++++++++++++---- platform/haiku/haiku_direct_window.h | 26 +++-- platform/haiku/haiku_gl_view.cpp | 45 ++------- platform/haiku/haiku_gl_view.h | 20 +--- platform/haiku/os_haiku.cpp | 29 ++++-- platform/haiku/os_haiku.h | 2 + 8 files changed, 227 insertions(+), 103 deletions(-) diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp index 5c82b187b3..8cb1adc360 100644 --- a/platform/haiku/context_gl_haiku.cpp +++ b/platform/haiku/context_gl_haiku.cpp @@ -2,18 +2,11 @@ #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) -ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow** p_window, OS::VideoMode& p_default_video_mode) { - video_mode = p_default_video_mode; - - uint32 type = BGL_RGB|BGL_DOUBLE|BGL_DEPTH; +ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow* p_window) { + window = p_window; - BRect windowRect; - windowRect.Set(50, 50, 800, 600); - - window = new HaikuDirectWindow(windowRect); + uint32 type = BGL_RGB | BGL_DOUBLE | BGL_DEPTH; view = new HaikuGLView(window->Bounds(), type); - - *p_window = window; } ContextGL_Haiku::~ContextGL_Haiku() { @@ -24,18 +17,18 @@ Error ContextGL_Haiku::initialize() { window->AddChild(view); view->LockGL(); window->SetHaikuGLView(view); - window->InitMessageRunner(); - window->Show(); return OK; } void ContextGL_Haiku::release_current() { - ERR_PRINT("release_current() NOT IMPLEMENTED"); + //ERR_PRINT("release_current() NOT IMPLEMENTED"); + view->UnlockGL(); } void ContextGL_Haiku::make_current() { - ERR_PRINT("make_current() NOT IMPLEMENTED"); + view->LockGL(); + //ERR_PRINT("make_current() NOT IMPLEMENTED"); } void ContextGL_Haiku::swap_buffers() { @@ -43,13 +36,11 @@ void ContextGL_Haiku::swap_buffers() { } int ContextGL_Haiku::get_window_width() { - // TODO: implement - return 800; + return window->Bounds().IntegerWidth(); } int ContextGL_Haiku::get_window_height() { - // TODO: implement - return 600; + return window->Bounds().IntegerHeight(); } #endif diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h index 16efa8f61d..e37fe14970 100644 --- a/platform/haiku/context_gl_haiku.h +++ b/platform/haiku/context_gl_haiku.h @@ -3,7 +3,6 @@ #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) -#include "os/os.h" #include "drivers/gl_context/context_gl.h" #include "haiku_direct_window.h" @@ -13,10 +12,9 @@ class ContextGL_Haiku : public ContextGL { private: HaikuGLView* view; HaikuDirectWindow* window; - OS::VideoMode video_mode; public: - ContextGL_Haiku(HaikuDirectWindow** p_window, OS::VideoMode& default_video_mode); + ContextGL_Haiku(HaikuDirectWindow* p_window); ~ContextGL_Haiku(); virtual Error initialize(); diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index e7f2718278..9c0696bc42 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -1,45 +1,186 @@ +#include "main/main.h" #include "haiku_direct_window.h" HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, 0) { - // TODO: formatting - float minWidth = 0.0f; - float maxWidth = 0.0f; - float minHeight = 0.0f; - float maxHeight = 0.0f; - - GetSizeLimits(&minWidth, &maxWidth, &minHeight, &maxHeight); - SetSizeLimits(50.0f, maxWidth, 50.0f, maxHeight); + last_mouse_pos_valid = false; + last_buttons_state = 0; } -HaikuDirectWindow::~HaikuDirectWindow() -{ - delete update_runner; +HaikuDirectWindow::~HaikuDirectWindow() { + if (update_runner) { + delete update_runner; + } } void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) { view = p_view; } -void HaikuDirectWindow::InitMessageRunner() { - update_runner = new BMessageRunner(BMessenger(view), +void HaikuDirectWindow::StartMessageRunner() { + update_runner = new BMessageRunner(BMessenger(this), new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */); } +void HaikuDirectWindow::StopMessageRunner() { + delete update_runner; +} -bool HaikuDirectWindow::QuitRequested() -{ +void HaikuDirectWindow::SetInput(InputDefault* p_input) { + input = p_input; +} + +bool HaikuDirectWindow::QuitRequested() { view->EnableDirectMode(false); be_app->PostMessage(B_QUIT_REQUESTED); return true; } - -void HaikuDirectWindow::DirectConnected(direct_buffer_info *info) -{ +void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) { view->DirectConnected(info); view->EnableDirectMode(true); } +void HaikuDirectWindow::MessageReceived(BMessage* message) +{ + switch (message->what) { + case REDRAW_MSG: + //ERR_PRINT("iteration 1"); + Main::iteration(); + + //if (NeedsUpdate()) { + // ERR_PRINT("NEEDS UPDATE"); + // Main::force_redraw(); + //} + + //ERR_PRINT("iteration 2"); + break; + + case B_INVALIDATE: + ERR_PRINT("WINDOW B_INVALIDATE"); + //Main::force_redraw(); + break; + + default: + BDirectWindow::MessageReceived(message); + } +} + +void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { + switch (message->what) { + case B_MOUSE_DOWN: + case B_MOUSE_UP: + DispatchMouseButton(message); + break; + + case B_MOUSE_MOVED: + DispatchMouseMoved(message); + break; + + default: + BDirectWindow::DispatchMessage(message, handler); + } +} + +void HaikuDirectWindow::DispatchMouseButton(BMessage* message) { + message->PrintToStream(); + + BPoint where; + if (message->FindPoint("where", &where) != B_OK) { + return; + } + + uint32 buttons = message->FindInt32("buttons"); + uint32 button = buttons ^ last_buttons_state; + last_buttons_state = buttons; + + // TODO: implement the mouse_mode checks + //if (mouse_mode == MOUSE_MODE_CAPTURED) { + // event.xbutton.x=last_mouse_pos.x; + // event.xbutton.y=last_mouse_pos.y; + //} + + InputEvent mouse_event; + mouse_event.ID = ++event_id; + mouse_event.type = InputEvent::MOUSE_BUTTON; + mouse_event.device = 0; + + // TODO: implement the modifier state getters + //mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state); + //mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state); + mouse_event.mouse_button.x = where.x; + mouse_event.mouse_button.y = where.y; + mouse_event.mouse_button.global_x = where.x; + mouse_event.mouse_button.global_y = where.y; + + switch (button) { + default: + case B_PRIMARY_MOUSE_BUTTON: + ERR_PRINT("PRIMARY"); + mouse_event.mouse_button.button_index = 1; + break; + + case B_SECONDARY_MOUSE_BUTTON: + ERR_PRINT("SECONDARY"); + mouse_event.mouse_button.button_index = 2; + break; + + case B_TERTIARY_MOUSE_BUTTON: + ERR_PRINT("MIDDLE"); + mouse_event.mouse_button.button_index = 3; + break; + } + + mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN); + + if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) { + int32 clicks = message->FindInt32("clicks"); + + if (clicks > 1) { + mouse_event.mouse_button.doubleclick=true; + } + } + + input->parse_input_event(mouse_event); +} + +void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { + BPoint where; + if (message->FindPoint("where", &where) != B_OK) { + return; + } + + Point2i pos(where.x, where.y); + + if (!last_mouse_pos_valid) { + last_mouse_pos=pos; + last_mouse_pos_valid=true; + } + + Point2i rel = pos - last_mouse_pos; + + InputEvent motion_event; + motion_event.ID = ++event_id; + motion_event.type = InputEvent::MOUSE_MOTION; + motion_event.device = 0; + + // TODO: implement the modifier state getters + //motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state); + //motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state); + motion_event.mouse_motion.x = pos.x; + motion_event.mouse_motion.y = pos.y; + input->set_mouse_pos(pos); + motion_event.mouse_motion.global_x = pos.x; + motion_event.mouse_motion.global_y = pos.y; + motion_event.mouse_motion.speed_x = input->get_mouse_speed().x; + motion_event.mouse_motion.speed_y = input->get_mouse_speed().y; + + motion_event.mouse_motion.relative_x = rel.x; + motion_event.mouse_motion.relative_y = rel.y; + + last_mouse_pos=pos; + + input->parse_input_event(motion_event); +} diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 450ea64296..19ea987e76 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -4,24 +4,38 @@ #include // needed for image_id #include +#include "os/input.h" #include "haiku_gl_view.h" #define REDRAW_MSG 'rdrw' class HaikuDirectWindow : public BDirectWindow { +private: + unsigned int event_id; + Point2i last_mouse_pos; + bool last_mouse_pos_valid; + uint32 last_buttons_state; + + InputDefault* input; + HaikuGLView* view; + BMessageRunner* update_runner; + + void DispatchMouseButton(BMessage* message); + void DispatchMouseMoved(BMessage* message); + public: HaikuDirectWindow(BRect p_frame); ~HaikuDirectWindow(); void SetHaikuGLView(HaikuGLView* p_view); - void InitMessageRunner(); + void StartMessageRunner(); + void StopMessageRunner(); + void SetInput(InputDefault* p_input); virtual bool QuitRequested(); - virtual void DirectConnected(direct_buffer_info *info); - -private: - HaikuGLView* view; - BMessageRunner* update_runner; + virtual void DirectConnected(direct_buffer_info* info); + virtual void MessageReceived(BMessage* message); + virtual void DispatchMessage(BMessage* message, BHandler* handler); }; #endif diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp index 61a0120656..8adab96a87 100644 --- a/platform/haiku/haiku_gl_view.cpp +++ b/platform/haiku/haiku_gl_view.cpp @@ -1,54 +1,31 @@ +#include "main/main.h" #include "haiku_gl_view.h" HaikuGLView::HaikuGLView(BRect frame, uint32 type) - : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type), rotate(0) + : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type) { - width = frame.right-frame.left; - height = frame.bottom-frame.top; } -void HaikuGLView::AttachedToWindow(void) -{ +void HaikuGLView::AttachedToWindow(void) { LockGL(); BGLView::AttachedToWindow(); UnlockGL(); MakeFocus(); } -void HaikuGLView::FrameResized(float newWidth, float newHeight) -{ -} - -void HaikuGLView::gDraw(float rotation) -{ -} - -void HaikuGLView::gReshape(int width, int height) -{ -} - -void HaikuGLView::Render(void) -{ - LockGL(); - SwapBuffers(); - UnlockGL(); +void HaikuGLView::Draw(BRect updateRect) { + Main::force_redraw(); } -void HaikuGLView::MessageReceived(BMessage * msg) +void HaikuGLView::MessageReceived(BMessage* msg) { + // TODO: remove if not needed switch (msg->what) { - case 'rdrw': - Render(); - /* Rotate a bit more */ - rotate++; - break; - - default: - BGLView::MessageReceived(msg); + default: + BGLView::MessageReceived(msg); } } -void HaikuGLView::KeyDown(const char *bytes, int32 numBytes) -{ - +void HaikuGLView::MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage) { + ERR_PRINT("MouseMoved()"); } diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h index 44d05fa27f..78ebb513a8 100644 --- a/platform/haiku/haiku_gl_view.h +++ b/platform/haiku/haiku_gl_view.h @@ -7,21 +7,11 @@ class HaikuGLView : public BGLView { public: - HaikuGLView(BRect frame, uint32 type); - virtual void AttachedToWindow(void); - virtual void FrameResized(float newWidth, float newHeight); - virtual void MessageReceived(BMessage * msg); - virtual void KeyDown(const char* bytes, int32 numBytes); - - void Render(void); - -private: - void gDraw(float rotation = 0); - void gReshape(int width, int height); - - float width; - float height; - float rotate; + HaikuGLView(BRect frame, uint32 type); + virtual void AttachedToWindow(void); + virtual void MessageReceived(BMessage* msg); + virtual void MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage); + virtual void Draw(BRect updateRect); }; #endif diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index bf96cf1716..193927238d 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -17,6 +17,8 @@ void OS_Haiku::run() { } main_loop->init(); + window->Show(); + window->StartMessageRunner(); /* while (true) { @@ -29,6 +31,7 @@ void OS_Haiku::run() { */ app->Run(); + window->StopMessageRunner(); delete app; main_loop->finish(); @@ -56,8 +59,13 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ app = new HaikuApplication(); + BRect frame; + frame.Set(50, 50, 50 + current_video_mode.width - 1, 50 + current_video_mode.height - 1); + + window = new HaikuDirectWindow(frame); + #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) - context_gl = memnew(ContextGL_Haiku(&window, current_video_mode)); + context_gl = memnew(ContextGL_Haiku(window)); context_gl->initialize(); rasterizer = memnew(RasterizerGLES2); @@ -67,9 +75,9 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ ERR_FAIL_COND(!visual_server); - if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { - visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); - } + //if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + // visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); + //} visual_server->init(); @@ -92,6 +100,9 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ spatial_sound_server->init(); spatial_sound_2d_server = memnew(SpatialSound2DServerSW); spatial_sound_2d_server->init(); + + input = memnew(InputDefault); + window->SetInput(input); } void OS_Haiku::finalize() { @@ -121,6 +132,8 @@ void OS_Haiku::finalize() { physics_2d_server->finish(); memdelete(physics_2d_server); + memdelete(input); + #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) memdelete(context_gl); #endif @@ -128,9 +141,7 @@ void OS_Haiku::finalize() { void OS_Haiku::set_main_loop(MainLoop* p_main_loop) { main_loop = p_main_loop; - - // TODO: enable - //input->set_main_loop(p_main_loop); + input->set_main_loop(p_main_loop); } MainLoop* OS_Haiku::get_main_loop() const { @@ -146,11 +157,11 @@ void OS_Haiku::delete_main_loop() { } void OS_Haiku::release_rendering_thread() { - ERR_PRINT("release_rendering_thread() NOT IMPLEMENTED"); + context_gl->release_current(); } void OS_Haiku::make_rendering_thread() { - ERR_PRINT("make_rendering_thread() NOT IMPLEMENTED"); + context_gl->make_current(); } bool OS_Haiku::can_draw() const { diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 938983347c..b741ae7da0 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -1,6 +1,7 @@ #ifndef OS_HAIKU_H #define OS_HAIKU_H +#include "os/input.h" #include "drivers/unix/os_unix.h" #include "servers/visual_server.h" #include "servers/visual/rasterizer.h" @@ -22,6 +23,7 @@ private: HaikuApplication* app; HaikuDirectWindow* window; MainLoop* main_loop; + InputDefault* input; Rasterizer* rasterizer; VisualServer* visual_server; VideoMode current_video_mode; -- cgit v1.2.3 From 2102d35e9c18a0cede87e7e45d375153702b3ea5 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Wed, 17 Jun 2015 22:27:45 +0300 Subject: Haiku: read the status of the key modifiers and mouse buttons --- platform/haiku/haiku_direct_window.cpp | 71 +++++++++++++++++++++++----------- platform/haiku/haiku_direct_window.h | 2 + 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 9c0696bc42..6ff4369087 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -39,7 +39,7 @@ bool HaikuDirectWindow::QuitRequested() { } void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) { - view->DirectConnected(info); + view->DirectConnected(info); view->EnableDirectMode(true); } @@ -49,21 +49,21 @@ void HaikuDirectWindow::MessageReceived(BMessage* message) case REDRAW_MSG: //ERR_PRINT("iteration 1"); Main::iteration(); - + //if (NeedsUpdate()) { // ERR_PRINT("NEEDS UPDATE"); // Main::force_redraw(); //} - + //ERR_PRINT("iteration 2"); break; - + case B_INVALIDATE: ERR_PRINT("WINDOW B_INVALIDATE"); //Main::force_redraw(); break; - default: + default: BDirectWindow::MessageReceived(message); } } @@ -92,6 +92,7 @@ void HaikuDirectWindow::DispatchMouseButton(BMessage* message) { return; } + uint32 modifiers = message->FindInt32("modifiers"); uint32 buttons = message->FindInt32("buttons"); uint32 button = buttons ^ last_buttons_state; last_buttons_state = buttons; @@ -101,15 +102,14 @@ void HaikuDirectWindow::DispatchMouseButton(BMessage* message) { // event.xbutton.x=last_mouse_pos.x; // event.xbutton.y=last_mouse_pos.y; //} - + InputEvent mouse_event; mouse_event.ID = ++event_id; mouse_event.type = InputEvent::MOUSE_BUTTON; mouse_event.device = 0; - // TODO: implement the modifier state getters - //mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state); - //mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state); + mouse_event.mouse_button.mod = GetKeyModifierState(modifiers); + mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons); mouse_event.mouse_button.x = where.x; mouse_event.mouse_button.y = where.y; mouse_event.mouse_button.global_x = where.x; @@ -118,30 +118,27 @@ void HaikuDirectWindow::DispatchMouseButton(BMessage* message) { switch (button) { default: case B_PRIMARY_MOUSE_BUTTON: - ERR_PRINT("PRIMARY"); mouse_event.mouse_button.button_index = 1; break; case B_SECONDARY_MOUSE_BUTTON: - ERR_PRINT("SECONDARY"); mouse_event.mouse_button.button_index = 2; break; case B_TERTIARY_MOUSE_BUTTON: - ERR_PRINT("MIDDLE"); mouse_event.mouse_button.button_index = 3; break; } - + mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN); if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) { int32 clicks = message->FindInt32("clicks"); - + if (clicks > 1) { mouse_event.mouse_button.doubleclick=true; } - } + } input->parse_input_event(mouse_event); } @@ -151,12 +148,14 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { if (message->FindPoint("where", &where) != B_OK) { return; } - + Point2i pos(where.x, where.y); - + uint32 modifiers = message->FindInt32("modifiers"); + uint32 buttons = message->FindInt32("buttons"); + if (!last_mouse_pos_valid) { - last_mouse_pos=pos; - last_mouse_pos_valid=true; + last_mouse_pos = pos; + last_mouse_pos_valid = true; } Point2i rel = pos - last_mouse_pos; @@ -166,9 +165,8 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { motion_event.type = InputEvent::MOUSE_MOTION; motion_event.device = 0; - // TODO: implement the modifier state getters - //motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state); - //motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state); + motion_event.mouse_motion.mod = GetKeyModifierState(modifiers); + motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons); motion_event.mouse_motion.x = pos.x; motion_event.mouse_motion.y = pos.y; input->set_mouse_pos(pos); @@ -184,3 +182,32 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { input->parse_input_event(motion_event); } + +inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) { + InputModifierState state; + + state.shift = (p_state & B_SHIFT_KEY) != 0; + state.control = (p_state & B_CONTROL_KEY) != 0; + state.alt = (p_state & B_OPTION_KEY) != 0; + state.meta = (p_state & B_COMMAND_KEY) != 0; + + return state; +} + +inline unsigned int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) { + unsigned int state = 0; + + if (p_state & B_PRIMARY_MOUSE_BUTTON) { + state |= 1 << 0; + } + + if (p_state & B_SECONDARY_MOUSE_BUTTON) { + state |= 1 << 1; + } + + if (p_state & B_TERTIARY_MOUSE_BUTTON) { + state |= 1 << 2; + } + + return state; +} diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 19ea987e76..bb0ef43da0 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -23,6 +23,8 @@ private: void DispatchMouseButton(BMessage* message); void DispatchMouseMoved(BMessage* message); + inline InputModifierState GetKeyModifierState(uint32 p_state); + inline unsigned int GetMouseButtonState(uint32 p_state); public: HaikuDirectWindow(BRect p_frame); -- cgit v1.2.3 From f10eb8ffa1a7f6bee9b5228ea1204fd93844e4cc Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Thu, 18 Jun 2015 22:41:33 +0300 Subject: Haiku: implement get_mouse_pos() and get_mouse_button_state() --- platform/haiku/haiku_direct_window.cpp | 13 ++++++++----- platform/haiku/haiku_direct_window.h | 8 ++++++-- platform/haiku/os_haiku.cpp | 7 +++---- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 6ff4369087..62231565a9 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -6,6 +6,7 @@ HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) { last_mouse_pos_valid = false; last_buttons_state = 0; + last_button_mask = 0; } @@ -154,11 +155,11 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { uint32 buttons = message->FindInt32("buttons"); if (!last_mouse_pos_valid) { - last_mouse_pos = pos; + last_mouse_position = pos; last_mouse_pos_valid = true; } - Point2i rel = pos - last_mouse_pos; + Point2i rel = pos - last_mouse_position; InputEvent motion_event; motion_event.ID = ++event_id; @@ -178,7 +179,7 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { motion_event.mouse_motion.relative_x = rel.x; motion_event.mouse_motion.relative_y = rel.y; - last_mouse_pos=pos; + last_mouse_position = pos; input->parse_input_event(motion_event); } @@ -194,8 +195,8 @@ inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) return state; } -inline unsigned int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) { - unsigned int state = 0; +inline int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) { + int state = 0; if (p_state & B_PRIMARY_MOUSE_BUTTON) { state |= 1 << 0; @@ -209,5 +210,7 @@ inline unsigned int HaikuDirectWindow::GetMouseButtonState(uint32 p_state) { state |= 1 << 2; } + last_button_mask = state; + return state; } diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index bb0ef43da0..be4dcd9e94 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -13,9 +13,10 @@ class HaikuDirectWindow : public BDirectWindow { private: unsigned int event_id; - Point2i last_mouse_pos; + Point2i last_mouse_position; bool last_mouse_pos_valid; uint32 last_buttons_state; + int last_button_mask; InputDefault* input; HaikuGLView* view; @@ -24,7 +25,7 @@ private: void DispatchMouseButton(BMessage* message); void DispatchMouseMoved(BMessage* message); inline InputModifierState GetKeyModifierState(uint32 p_state); - inline unsigned int GetMouseButtonState(uint32 p_state); + inline int GetMouseButtonState(uint32 p_state); public: HaikuDirectWindow(BRect p_frame); @@ -38,6 +39,9 @@ public: virtual void DirectConnected(direct_buffer_info* info); virtual void MessageReceived(BMessage* message); virtual void DispatchMessage(BMessage* message, BHandler* handler); + + inline Point2i GetLastMousePosition() { return last_mouse_position; }; + inline int GetLastButtonMask() { return last_button_mask; }; }; #endif diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 193927238d..3694244e0a 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -174,19 +174,18 @@ void OS_Haiku::swap_buffers() { } Point2 OS_Haiku::get_mouse_pos() const { - ERR_PRINT("get_mouse_pos() NOT IMPLEMENTED"); + return window->GetLastMousePosition(); } int OS_Haiku::get_mouse_button_state() const { - ERR_PRINT("get_mouse_button_state() NOT IMPLEMENTED"); + return window->GetLastButtonMask(); } void OS_Haiku::set_cursor_shape(CursorShape p_shape) { - ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED"); + //ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED"); } void OS_Haiku::set_window_title(const String& p_title) { - //ERR_PRINT("set_window_title() NOT IMPLEMENTED"); window->SetTitle(p_title.utf8().get_data()); } -- cgit v1.2.3 From 93ac4ace0a0d84fdd7003fcaa02296d55ad5b2ad Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sat, 20 Jun 2015 01:59:32 +0300 Subject: Haiku: handle the quit request message --- platform/haiku/haiku_direct_window.cpp | 32 +++++++++++++------------------- platform/haiku/haiku_direct_window.h | 2 ++ platform/haiku/os_haiku.cpp | 3 +++ 3 files changed, 18 insertions(+), 19 deletions(-) diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 62231565a9..3fccab10dd 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -2,7 +2,7 @@ #include "haiku_direct_window.h" HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) - : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, 0) + : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) { last_mouse_pos_valid = false; last_buttons_state = 0; @@ -33,10 +33,13 @@ void HaikuDirectWindow::SetInput(InputDefault* p_input) { input = p_input; } +void HaikuDirectWindow::SetMainLoop(MainLoop* p_main_loop) { + main_loop = p_main_loop; +} + bool HaikuDirectWindow::QuitRequested() { - view->EnableDirectMode(false); - be_app->PostMessage(B_QUIT_REQUESTED); - return true; + main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); + return false; } void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) { @@ -44,24 +47,15 @@ void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) { view->EnableDirectMode(true); } -void HaikuDirectWindow::MessageReceived(BMessage* message) -{ +void HaikuDirectWindow::MessageReceived(BMessage* message) { switch (message->what) { case REDRAW_MSG: - //ERR_PRINT("iteration 1"); - Main::iteration(); - - //if (NeedsUpdate()) { - // ERR_PRINT("NEEDS UPDATE"); - // Main::force_redraw(); - //} - - //ERR_PRINT("iteration 2"); - break; + Sync(); - case B_INVALIDATE: - ERR_PRINT("WINDOW B_INVALIDATE"); - //Main::force_redraw(); + if (Main::iteration() == true) { + view->EnableDirectMode(false); + Quit(); + } break; default: diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index be4dcd9e94..c985cdc5d6 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -18,6 +18,7 @@ private: uint32 last_buttons_state; int last_button_mask; + MainLoop* main_loop; InputDefault* input; HaikuGLView* view; BMessageRunner* update_runner; @@ -35,6 +36,7 @@ public: void StartMessageRunner(); void StopMessageRunner(); void SetInput(InputDefault* p_input); + void SetMainLoop(MainLoop* p_main_loop); virtual bool QuitRequested(); virtual void DirectConnected(direct_buffer_info* info); virtual void MessageReceived(BMessage* message); diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 3694244e0a..699b0ba1ce 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -29,6 +29,7 @@ void OS_Haiku::run() { } } */ + app->Run(); window->StopMessageRunner(); @@ -142,6 +143,7 @@ void OS_Haiku::finalize() { void OS_Haiku::set_main_loop(MainLoop* p_main_loop) { main_loop = p_main_loop; input->set_main_loop(p_main_loop); + window->SetMainLoop(p_main_loop); } MainLoop* OS_Haiku::get_main_loop() const { @@ -154,6 +156,7 @@ void OS_Haiku::delete_main_loop() { } main_loop = NULL; + window->SetMainLoop(NULL); } void OS_Haiku::release_rendering_thread() { -- cgit v1.2.3 From d44dfc244099eafe40ff0d48abbcefd4271d029b Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sat, 20 Jun 2015 03:43:11 +0300 Subject: Haiku: cleanup, add TODOs --- platform/haiku/os_haiku.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 699b0ba1ce..7e4bb83177 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -2,6 +2,7 @@ #include "servers/visual/visual_server_wrap_mt.h" #include "drivers/gles2/rasterizer_gles2.h" #include "servers/physics/physics_server_sw.h" +//#include "servers/physics_2d/physics_2d_server_wrap_mt.h" #include "main/main.h" #include "os_haiku.h" @@ -19,22 +20,10 @@ void OS_Haiku::run() { main_loop->init(); window->Show(); window->StartMessageRunner(); - - /* - while (true) { - // TODO: process events - - if (Main::iteration() == true) { - break; - } - } - */ - - app->Run(); window->StopMessageRunner(); - delete app; + delete app; main_loop->finish(); } @@ -76,6 +65,7 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ ERR_FAIL_COND(!visual_server); + // TODO: enable multithreaded VS //if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { // visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); //} @@ -85,6 +75,8 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ physics_server = memnew(PhysicsServerSW); physics_server->init(); physics_2d_server = memnew(Physics2DServerSW); + // TODO: enable multithreaded PS + //physics_2d_server = Physics2DServerWrapMT::init_server(); physics_2d_server->init(); AudioDriverManagerSW::get_driver(p_audio_driver)->set_singleton(); -- cgit v1.2.3 From b59e95ce1c9905af8c7d44b74082ac489520e9b2 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sat, 20 Jun 2015 15:35:54 +0300 Subject: Haiku: implemet get_widow_size() get/set_window_position() --- platform/haiku/os_haiku.cpp | 13 ++++++++++++- platform/haiku/os_haiku.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 7e4bb83177..1dc16f7e1c 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -185,7 +185,18 @@ void OS_Haiku::set_window_title(const String& p_title) { } Size2 OS_Haiku::get_window_size() const { - ERR_PRINT("get_window_size() NOT IMPLEMENTED"); + BSize size = window->Size(); + return Size2i(size.IntegerWidth(), size.IntegerHeight()); +} + +Point2 OS_Haiku::get_window_position() const { + BPoint point(0, 0); + window->ConvertToScreen(&point); + return Point2i(point.x, point.y); +} + +void OS_Haiku::set_window_position(const Point2& p_position) { + window->MoveTo(p_position.x, p_position.y); } void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) { diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index b741ae7da0..59f47fa11f 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -71,6 +71,8 @@ public: virtual void set_window_title(const String& p_title); virtual Size2 get_window_size() const; + virtual Point2 get_window_position() const; + virtual void set_window_position(const Point2& p_position); virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0); virtual VideoMode get_video_mode(int p_screen=0) const; -- cgit v1.2.3 From 6f48ddc61db9a06e0751356e712fc87ded9ae3c3 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sun, 21 Jun 2015 02:08:31 +0300 Subject: Haiku: add some screen and window-related methods --- platform/haiku/os_haiku.cpp | 49 ++++++++++++++++++++++++++++++++++++++++++++- platform/haiku/os_haiku.h | 8 ++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 1dc16f7e1c..230340f325 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -1,3 +1,5 @@ +#include + #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" #include "drivers/gles2/rasterizer_gles2.h" @@ -180,13 +182,48 @@ void OS_Haiku::set_cursor_shape(CursorShape p_shape) { //ERR_PRINT("set_cursor_shape() NOT IMPLEMENTED"); } +int OS_Haiku::get_screen_count() const { + // TODO: implement get_screen_count() + return 1; +} + +int OS_Haiku::get_current_screen() const { + // TODO: implement get_current_screen() + return 0; +} + +void OS_Haiku::set_current_screen(int p_screen) { + // TODO: implement set_current_screen() +} + +Point2 OS_Haiku::get_screen_position(int p_screen) const { + // TODO: make this work with the p_screen parameter + BScreen* screen = new BScreen(window); + BRect frame = screen->Frame(); + delete screen; + return Point2i(frame.left, frame.top); +} + +Size2 OS_Haiku::get_screen_size(int p_screen) const { + // TODO: make this work with the p_screen parameter + BScreen* screen = new BScreen(window); + BRect frame = screen->Frame(); + delete screen; + return Size2i(frame.IntegerWidth() + 1, frame.IntegerHeight() + 1); +} + void OS_Haiku::set_window_title(const String& p_title) { window->SetTitle(p_title.utf8().get_data()); } Size2 OS_Haiku::get_window_size() const { BSize size = window->Size(); - return Size2i(size.IntegerWidth(), size.IntegerHeight()); + return Size2i(size.IntegerWidth() + 1, size.IntegerHeight() + 1); +} + +void OS_Haiku::set_window_size(const Size2 p_size) { + // TODO: why does it stop redrawing after this is called? + window->ResizeTo(p_size.x, p_size.y); } Point2 OS_Haiku::get_window_position() const { @@ -199,6 +236,16 @@ void OS_Haiku::set_window_position(const Point2& p_position) { window->MoveTo(p_position.x, p_position.y); } +void OS_Haiku::set_window_fullscreen(bool p_enabled) { + window->SetFullScreen(p_enabled); + current_video_mode.fullscreen = p_enabled; + visual_server->init(); +} + +bool OS_Haiku::is_window_fullscreen() const { + return current_video_mode.fullscreen; +} + void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) { ERR_PRINT("set_video_mode() NOT IMPLEMENTED"); } diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 59f47fa11f..983fbc33a9 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -69,10 +69,18 @@ public: virtual int get_mouse_button_state() const; virtual void set_cursor_shape(CursorShape p_shape); + virtual int get_screen_count() const; + virtual int get_current_screen() const; + virtual void set_current_screen(int p_screen); + virtual Point2 get_screen_position(int p_screen=0) const; + virtual Size2 get_screen_size(int p_screen=0) const; virtual void set_window_title(const String& p_title); virtual Size2 get_window_size() const; + virtual void set_window_size(const Size2 p_size); virtual Point2 get_window_position() const; virtual void set_window_position(const Point2& p_position); + virtual void set_window_fullscreen(bool p_enabled); + virtual bool is_window_fullscreen() const; virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0); virtual VideoMode get_video_mode(int p_screen=0) const; -- cgit v1.2.3 From 174df9a276b26eb6594e3387f71e3fe8c1706253 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sun, 21 Jun 2015 22:18:27 +0300 Subject: Haiku: add support for mouse wheel --- platform/haiku/haiku_direct_window.cpp | 33 +++++++++++++++++++++++++++++++++ platform/haiku/haiku_direct_window.h | 2 ++ 2 files changed, 35 insertions(+) diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 3fccab10dd..8c8069af49 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -7,6 +7,7 @@ HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) last_mouse_pos_valid = false; last_buttons_state = 0; last_button_mask = 0; + last_key_modifier_state = 0; } @@ -74,6 +75,10 @@ void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { DispatchMouseMoved(message); break; + case B_MOUSE_WHEEL_CHANGED: + DispatchMouseWheelChanged(message); + break; + default: BDirectWindow::DispatchMessage(message, handler); } @@ -178,7 +183,35 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { input->parse_input_event(motion_event); } +void HaikuDirectWindow::DispatchMouseWheelChanged(BMessage* message) { + float wheel_delta_y = 0; + if (message->FindFloat("be:wheel_delta_y", &wheel_delta_y) != B_OK) { + return; + } + + InputEvent mouse_event; + mouse_event.ID = ++event_id; + mouse_event.type = InputEvent::MOUSE_BUTTON; + mouse_event.device = 0; + + mouse_event.mouse_button.button_index = wheel_delta_y < 0 ? 4 : 5; + mouse_event.mouse_button.mod = GetKeyModifierState(last_key_modifier_state); + mouse_event.mouse_button.button_mask = last_button_mask; + mouse_event.mouse_button.x = last_mouse_position.x; + mouse_event.mouse_button.y = last_mouse_position.y; + mouse_event.mouse_button.global_x = last_mouse_position.x; + mouse_event.mouse_button.global_y = last_mouse_position.y; + + mouse_event.mouse_button.pressed = true; + input->parse_input_event(mouse_event); + + mouse_event.ID = ++event_id; + mouse_event.mouse_button.pressed = false; + input->parse_input_event(mouse_event); +} + inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) { + last_key_modifier_state = p_state; InputModifierState state; state.shift = (p_state & B_SHIFT_KEY) != 0; diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index c985cdc5d6..5355ab4dd4 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -16,6 +16,7 @@ private: Point2i last_mouse_position; bool last_mouse_pos_valid; uint32 last_buttons_state; + uint32 last_key_modifier_state; int last_button_mask; MainLoop* main_loop; @@ -25,6 +26,7 @@ private: void DispatchMouseButton(BMessage* message); void DispatchMouseMoved(BMessage* message); + void DispatchMouseWheelChanged(BMessage* message); inline InputModifierState GetKeyModifierState(uint32 p_state); inline int GetMouseButtonState(uint32 p_state); -- cgit v1.2.3 From 7ad89c7e8383144292609f857803a4c57f852259 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Tue, 23 Jun 2015 21:22:12 +0300 Subject: Haiku: implement some more window-related methods --- platform/haiku/os_haiku.cpp | 44 +++++++++++++++++++++++++++++++++++++++++++- platform/haiku/os_haiku.h | 6 ++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 230340f325..b4b7877038 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -20,7 +20,6 @@ void OS_Haiku::run() { } main_loop->init(); - window->Show(); window->StartMessageRunner(); app->Run(); window->StopMessageRunner(); @@ -56,6 +55,16 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ window = new HaikuDirectWindow(frame); + if (current_video_mode.fullscreen) { + window->SetFullScreen(true); + } + + if (!current_video_mode.resizable) { + uint32 flags = window->Flags(); + flags |= B_NOT_RESIZABLE; + window->SetFlags(flags); + } + #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) context_gl = memnew(ContextGL_Haiku(window)); context_gl->initialize(); @@ -98,6 +107,7 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ input = memnew(InputDefault); window->SetInput(input); + window->Show(); } void OS_Haiku::finalize() { @@ -246,6 +256,38 @@ bool OS_Haiku::is_window_fullscreen() const { return current_video_mode.fullscreen; } +void OS_Haiku::set_window_resizable(bool p_enabled) { + uint32 flags = window->Flags(); + + if (p_enabled) { + flags &= ~(B_NOT_RESIZABLE); + } else { + flags |= B_NOT_RESIZABLE; + } + + window->SetFlags(flags); +} + +bool OS_Haiku::is_window_resizable() const { + return !(window->Flags() & B_NOT_RESIZABLE); +} + +void OS_Haiku::set_window_minimized(bool p_enabled) { + window->Minimize(p_enabled); +} + +bool OS_Haiku::is_window_minimized() const { + return window->IsMinimized(); +} + +void OS_Haiku::set_window_maximized(bool p_enabled) { + window->Minimize(!p_enabled); +} + +bool OS_Haiku::is_window_maximized() const { + return !window->IsMinimized(); +} + void OS_Haiku::set_video_mode(const VideoMode& p_video_mode, int p_screen) { ERR_PRINT("set_video_mode() NOT IMPLEMENTED"); } diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 983fbc33a9..a7a8bee522 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -81,6 +81,12 @@ public: virtual void set_window_position(const Point2& p_position); virtual void set_window_fullscreen(bool p_enabled); virtual bool is_window_fullscreen() const; + virtual void set_window_resizable(bool p_enabled); + virtual bool is_window_resizable() const; + virtual void set_window_minimized(bool p_enabled); + virtual bool is_window_minimized() const; + virtual void set_window_maximized(bool p_enabled); + virtual bool is_window_maximized() const; virtual void set_video_mode(const VideoMode& p_video_mode, int p_screen=0); virtual VideoMode get_video_mode(int p_screen=0) const; -- cgit v1.2.3 From f61eb5fd8e13642c82364f8ee66a0f6c791a4511 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Fri, 26 Jun 2015 21:32:57 +0300 Subject: Haiku: fix the glew.c hack --- drivers/gl_context/glew.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gl_context/glew.c b/drivers/gl_context/glew.c index e38942de4f..962e82b657 100644 --- a/drivers/gl_context/glew.c +++ b/drivers/gl_context/glew.c @@ -1,4 +1,8 @@ -#ifndef GLEW_ENABLED +#ifdef __HAIKU__ + #undef GLEW_ENABLED +#endif + +#ifdef GLEW_ENABLED /* ** The OpenGL Extension Wrangler Library ** Copyright (C) 2002-2008, Milan Ikits -- cgit v1.2.3 From 903e6b37c0ed94cd0b3447dd3ff471abbfaa4460 Mon Sep 17 00:00:00 2001 From: volzhs Date: Mon, 29 Jun 2015 02:56:38 +0900 Subject: fix crash by payments when run on android 5.1.1 device. (http://stackoverflow.com/questions/24480069/google-in-app-billing-illegalargumentexception-service-intent-must-be-explicit) --- .../android/java/src/com/android/godot/payments/PaymentsManager.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java index fd1a62738a..5bf86d0b69 100644 --- a/platform/android/java/src/com/android/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/com/android/godot/payments/PaymentsManager.java @@ -47,8 +47,10 @@ public class PaymentsManager { } public PaymentsManager initService(){ + Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND"); + intent.setPackage("com.android.vending"); activity.bindService( - new Intent("com.android.vending.billing.InAppBillingService.BIND"), + intent, mServiceConn, Context.BIND_AUTO_CREATE); return this; -- cgit v1.2.3 From 77e78cdb200b08a079b9d4047ea99227874ff3e1 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Thu, 2 Jul 2015 18:41:32 +0300 Subject: Haiku: gl context locking --- platform/haiku/context_gl_haiku.cpp | 3 --- platform/haiku/haiku_direct_window.cpp | 42 ++++++++++++++++++++++++++++------ platform/haiku/haiku_direct_window.h | 12 +++++++--- platform/haiku/os_haiku.cpp | 23 +++++++++++++++---- 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp index 8cb1adc360..21107a52a4 100644 --- a/platform/haiku/context_gl_haiku.cpp +++ b/platform/haiku/context_gl_haiku.cpp @@ -15,20 +15,17 @@ ContextGL_Haiku::~ContextGL_Haiku() { Error ContextGL_Haiku::initialize() { window->AddChild(view); - view->LockGL(); window->SetHaikuGLView(view); return OK; } void ContextGL_Haiku::release_current() { - //ERR_PRINT("release_current() NOT IMPLEMENTED"); view->UnlockGL(); } void ContextGL_Haiku::make_current() { view->LockGL(); - //ERR_PRINT("make_current() NOT IMPLEMENTED"); } void ContextGL_Haiku::swap_buffers() { diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 8c8069af49..e400d70108 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -23,7 +23,7 @@ void HaikuDirectWindow::SetHaikuGLView(HaikuGLView* p_view) { void HaikuDirectWindow::StartMessageRunner() { update_runner = new BMessageRunner(BMessenger(this), - new BMessage(REDRAW_MSG), 1000000/60 /* 60 fps */); + new BMessage(REDRAW_MSG), 1000000/30 /* 30 fps */); } void HaikuDirectWindow::StopMessageRunner() { @@ -68,15 +68,31 @@ void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { switch (message->what) { case B_MOUSE_DOWN: case B_MOUSE_UP: - DispatchMouseButton(message); + HandleMouseButton(message); break; case B_MOUSE_MOVED: - DispatchMouseMoved(message); + HandleMouseMoved(message); break; case B_MOUSE_WHEEL_CHANGED: - DispatchMouseWheelChanged(message); + HandleMouseWheelChanged(message); + break; + + case B_WINDOW_RESIZED: + HandleWindowResized(message); + //view->UnlockGL(); + //BDirectWindow::DispatchMessage(message, handler); + //view->LockGL(); + break; + + case LOCKGL_MSG: + ERR_PRINT("LOCKGL"); + view->LockGL(); + break; + + case UNLOCKGL_MSG: + view->UnlockGL(); break; default: @@ -84,7 +100,7 @@ void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { } } -void HaikuDirectWindow::DispatchMouseButton(BMessage* message) { +void HaikuDirectWindow::HandleMouseButton(BMessage* message) { message->PrintToStream(); BPoint where; @@ -143,7 +159,7 @@ void HaikuDirectWindow::DispatchMouseButton(BMessage* message) { input->parse_input_event(mouse_event); } -void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { +void HaikuDirectWindow::HandleMouseMoved(BMessage* message) { BPoint where; if (message->FindPoint("where", &where) != B_OK) { return; @@ -183,7 +199,7 @@ void HaikuDirectWindow::DispatchMouseMoved(BMessage* message) { input->parse_input_event(motion_event); } -void HaikuDirectWindow::DispatchMouseWheelChanged(BMessage* message) { +void HaikuDirectWindow::HandleMouseWheelChanged(BMessage* message) { float wheel_delta_y = 0; if (message->FindFloat("be:wheel_delta_y", &wheel_delta_y) != B_OK) { return; @@ -210,6 +226,18 @@ void HaikuDirectWindow::DispatchMouseWheelChanged(BMessage* message) { input->parse_input_event(mouse_event); } +void HaikuDirectWindow::HandleWindowResized(BMessage* message) { + int32 width = 0; + int32 height = 0; + + if ((message->FindInt32("width", &width) != B_OK) || (message->FindInt32("height", &height) != B_OK)) { + return; + } + + current_video_mode->width = width; + current_video_mode->height = height; +} + inline InputModifierState HaikuDirectWindow::GetKeyModifierState(uint32 p_state) { last_key_modifier_state = p_state; InputModifierState state; diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 5355ab4dd4..3667eb24d1 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -5,9 +5,12 @@ #include #include "os/input.h" +#include "core/os/os.h" #include "haiku_gl_view.h" #define REDRAW_MSG 'rdrw' +#define LOCKGL_MSG 'glck' +#define UNLOCKGL_MSG 'ulck' class HaikuDirectWindow : public BDirectWindow { @@ -18,15 +21,17 @@ private: uint32 last_buttons_state; uint32 last_key_modifier_state; int last_button_mask; + OS::VideoMode* current_video_mode; MainLoop* main_loop; InputDefault* input; HaikuGLView* view; BMessageRunner* update_runner; - void DispatchMouseButton(BMessage* message); - void DispatchMouseMoved(BMessage* message); - void DispatchMouseWheelChanged(BMessage* message); + void HandleMouseButton(BMessage* message); + void HandleMouseMoved(BMessage* message); + void HandleMouseWheelChanged(BMessage* message); + void HandleWindowResized(BMessage* message); inline InputModifierState GetKeyModifierState(uint32 p_state); inline int GetMouseButtonState(uint32 p_state); @@ -39,6 +44,7 @@ public: void StopMessageRunner(); void SetInput(InputDefault* p_input); void SetMainLoop(MainLoop* p_main_loop); + inline void SetVideoMode(OS::VideoMode* video_mode) { current_video_mode = video_mode; }; virtual bool QuitRequested(); virtual void DirectConnected(direct_buffer_info* info); virtual void MessageReceived(BMessage* message); diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index b4b7877038..2c29260281 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -20,11 +20,21 @@ void OS_Haiku::run() { } main_loop->init(); + context_gl->release_current(); + + // TODO: clean up + BMessenger* bms = new BMessenger(window); + BMessage* msg = new BMessage(); + bms->SendMessage(LOCKGL_MSG, msg); + window->StartMessageRunner(); app->Run(); window->StopMessageRunner(); delete app; + + delete bms; + delete msg; main_loop->finish(); } @@ -54,6 +64,7 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ frame.Set(50, 50, 50 + current_video_mode.width - 1, 50 + current_video_mode.height - 1); window = new HaikuDirectWindow(frame); + window->SetVideoMode(¤t_video_mode); if (current_video_mode.fullscreen) { window->SetFullScreen(true); @@ -68,6 +79,7 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) context_gl = memnew(ContextGL_Haiku(window)); context_gl->initialize(); + context_gl->make_current(); rasterizer = memnew(RasterizerGLES2); #endif @@ -81,6 +93,10 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ // visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); //} + input = memnew(InputDefault); + window->SetInput(input); + + window->Show(); visual_server->init(); physics_server = memnew(PhysicsServerSW); @@ -104,10 +120,6 @@ void OS_Haiku::initialize(const VideoMode& p_desired, int p_video_driver, int p_ spatial_sound_server->init(); spatial_sound_2d_server = memnew(SpatialSound2DServerSW); spatial_sound_2d_server->init(); - - input = memnew(InputDefault); - window->SetInput(input); - window->Show(); } void OS_Haiku::finalize() { @@ -266,10 +278,11 @@ void OS_Haiku::set_window_resizable(bool p_enabled) { } window->SetFlags(flags); + current_video_mode.resizable = p_enabled; } bool OS_Haiku::is_window_resizable() const { - return !(window->Flags() & B_NOT_RESIZABLE); + return current_video_mode.resizable; } void OS_Haiku::set_window_minimized(bool p_enabled) { -- cgit v1.2.3 From a009fadfff40d6339031a70c760103c76edfdce7 Mon Sep 17 00:00:00 2001 From: Peace Sells Date: Thu, 9 Jul 2015 20:51:49 -0600 Subject: Added GridMap settings which allows the user to enter a pick distance. --- modules/gridmap/grid_map_editor_plugin.cpp | 24 ++++++++++++++++++++++-- modules/gridmap/grid_map_editor_plugin.h | 7 +++++-- tools/editor/editor_settings.cpp | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 3d56b04cac..e4559ca100 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -220,7 +220,9 @@ void GridMapEditor::_menu_option(int p_option) { } break; - + case MENU_OPTION_GRIDMAP_SETTINGS: { + settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50)); + } break; } } @@ -304,7 +306,7 @@ bool GridMapEditor::do_input_action(Camera* p_camera,const Point2& p_point,bool p.d=edit_floor[edit_axis]*node->get_cell_size(); Vector3 inters; - if (!p.intersects_segment(from,from+normal*500,&inters)) + if (!p.intersects_segment(from, from + normal * settings_pick_distance->get_val(), &inters)) return false; @@ -1249,6 +1251,24 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) { //options->get_popup()->add_separator(); //options->get_popup()->add_item("Configure",MENU_OPTION_CONFIGURE); + options->get_popup()->add_separator(); + options->get_popup()->add_item("Settings", MENU_OPTION_GRIDMAP_SETTINGS); + + settings_dialog = memnew(ConfirmationDialog); + settings_dialog->set_title("GridMap Settings"); + add_child(settings_dialog); + settings_vbc = memnew(VBoxContainer); + settings_vbc->set_custom_minimum_size(Size2(200, 0)); + settings_dialog->add_child(settings_vbc); + settings_dialog->set_child_rect(settings_vbc); + + settings_pick_distance = memnew(SpinBox); + settings_pick_distance->set_max(10000.0f); + settings_pick_distance->set_min(500.0f); + settings_pick_distance->set_step(1.0f); + settings_pick_distance->set_val(EDITOR_DEF("gridmap_editor/pick_distance", 5000.0)); + settings_vbc->add_margin_child("Pick Distance:", settings_pick_distance); + clip_mode=CLIP_DISABLED; options->get_popup()->connect("item_pressed", this,"_menu_option"); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index 26fe8f20dc..03b2d4226e 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -78,6 +78,9 @@ class GridMapEditor : public VBoxContainer { ToolButton *mode_thumbnail; ToolButton *mode_list; HBoxContainer *spatial_editor_hb; + ConfirmationDialog *settings_dialog; + VBoxContainer *settings_vbc; + SpinBox *settings_pick_distance; struct SetItem { @@ -165,8 +168,8 @@ class GridMapEditor : public VBoxContainer { MENU_OPTION_SELECTION_MAKE_AREA, MENU_OPTION_SELECTION_MAKE_EXTERIOR_CONNECTOR, MENU_OPTION_SELECTION_CLEAR, - MENU_OPTION_REMOVE_AREA - + MENU_OPTION_REMOVE_AREA, + MENU_OPTION_GRIDMAP_SETTINGS }; diff --git a/tools/editor/editor_settings.cpp b/tools/editor/editor_settings.cpp index 0df9fcadef..f16f7c2992 100644 --- a/tools/editor/editor_settings.cpp +++ b/tools/editor/editor_settings.cpp @@ -443,6 +443,7 @@ void EditorSettings::_load_defaults() { set("scenetree_editor/duplicate_node_name_num_separator",0); hints["scenetree_editor/duplicate_node_name_num_separator"]=PropertyInfo(Variant::INT,"scenetree_editor/duplicate_node_name_num_separator",PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"); + set("gridmap_editor/pick_distance", 5000.0); set("3d_editor/default_fov",45.0); set("3d_editor/default_z_near",0.1); -- cgit v1.2.3 From db440a2a58a9f783322ffc528fe50e832f5ae50c Mon Sep 17 00:00:00 2001 From: sheepandshepherd Date: Fri, 10 Jul 2015 21:33:44 +0200 Subject: Fix List::move_before for front and back elements --- core/list.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/core/list.h b/core/list.h index 6deb150ef6..018abca940 100644 --- a/core/list.h +++ b/core/list.h @@ -518,10 +518,16 @@ public: if (value->prev_ptr) { value->prev_ptr->next_ptr = value->next_ptr; - }; + } + else { + _data->first = value->next_ptr; + } if (value->next_ptr) { value->next_ptr->prev_ptr = value->prev_ptr; - }; + } + else { + _data->last = value->prev_ptr; + } value->next_ptr = where; if (!where) { -- cgit v1.2.3 From 07e76a3f2ce85c996ddddce8e4e5180c7b948490 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sun, 12 Jul 2015 00:52:47 +0300 Subject: Haiku: add keyboard support --- platform/haiku/SCsub | 3 +- platform/haiku/haiku_direct_window.cpp | 84 ++++++++++++++ platform/haiku/haiku_direct_window.h | 2 + platform/haiku/key_mapping_haiku.cpp | 193 +++++++++++++++++++++++++++++++++ platform/haiku/key_mapping_haiku.h | 13 +++ 5 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 platform/haiku/key_mapping_haiku.cpp create mode 100644 platform/haiku/key_mapping_haiku.h diff --git a/platform/haiku/SCsub b/platform/haiku/SCsub index 18fa2e2b15..88c9b8b464 100644 --- a/platform/haiku/SCsub +++ b/platform/haiku/SCsub @@ -5,7 +5,8 @@ common_haiku = [ 'context_gl_haiku.cpp', 'haiku_application.cpp', 'haiku_direct_window.cpp', - 'haiku_gl_view.cpp' + 'haiku_gl_view.cpp', + 'key_mapping_haiku.cpp' ] env.Program( diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index e400d70108..e7577602ca 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -1,5 +1,9 @@ +#include + #include "main/main.h" +#include "os/keyboard.h" #include "haiku_direct_window.h" +#include "key_mapping_haiku.h" HaikuDirectWindow::HaikuDirectWindow(BRect p_frame) : BDirectWindow(p_frame, "Godot", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) @@ -79,6 +83,15 @@ void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { HandleMouseWheelChanged(message); break; + case B_KEY_DOWN: + case B_KEY_UP: + HandleKeyboardEvent(message); + break; + + case B_MODIFIERS_CHANGED: + HandleKeyboardModifierEvent(message); + break; + case B_WINDOW_RESIZED: HandleWindowResized(message); //view->UnlockGL(); @@ -226,6 +239,77 @@ void HaikuDirectWindow::HandleMouseWheelChanged(BMessage* message) { input->parse_input_event(mouse_event); } +void HaikuDirectWindow::HandleKeyboardEvent(BMessage* message) { + message->PrintToStream(); + int32 raw_char = 0; + int32 key = 0; + int32 modifiers = 0; + + if (message->FindInt32("raw_char", &raw_char) != B_OK) { + return; + } + + if (message->FindInt32("key", &key) != B_OK) { + return; + } + + if (message->FindInt32("modifiers", &modifiers) != B_OK) { + return; + } + + InputEvent event; + event.ID = ++event_id; + event.type = InputEvent::KEY; + event.device = 0; + event.key.mod = GetKeyModifierState(modifiers); + event.key.pressed = (message->what == B_KEY_DOWN); + event.key.scancode = KeyMappingHaiku::get_keysym(raw_char, key); + event.key.echo = message->HasInt32("be:key_repeat"); + event.key.unicode = 0; + + const char* bytes = NULL; + if (message->FindString("bytes", &bytes) == B_OK) { + event.key.unicode = BUnicodeChar::FromUTF8(&bytes); + } + + //make it consistent accross platforms. + if (event.key.scancode==KEY_BACKTAB) { + event.key.scancode=KEY_TAB; + event.key.mod.shift=true; + } + + input->parse_input_event(event); +} + +void HaikuDirectWindow::HandleKeyboardModifierEvent(BMessage* message) { + message->PrintToStream(); + + int32 old_modifiers = 0; + int32 modifiers = 0; + + if (message->FindInt32("be:old_modifiers", &old_modifiers) != B_OK) { + return; + } + + if (message->FindInt32("modifiers", &modifiers) != B_OK) { + return; + } + + int32 key = old_modifiers ^ modifiers; + + InputEvent event; + event.ID = ++event_id; + event.type = InputEvent::KEY; + event.device = 0; + event.key.mod = GetKeyModifierState(modifiers); + event.key.pressed = ((modifiers & key) != 0); + event.key.scancode = KeyMappingHaiku::get_modifier_keysym(key); + event.key.echo = false; + event.key.unicode = 0; + + input->parse_input_event(event); +} + void HaikuDirectWindow::HandleWindowResized(BMessage* message) { int32 width = 0; int32 height = 0; diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 3667eb24d1..7b1fd851fa 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -32,6 +32,8 @@ private: void HandleMouseMoved(BMessage* message); void HandleMouseWheelChanged(BMessage* message); void HandleWindowResized(BMessage* message); + void HandleKeyboardEvent(BMessage* message); + void HandleKeyboardModifierEvent(BMessage* message); inline InputModifierState GetKeyModifierState(uint32 p_state); inline int GetMouseButtonState(uint32 p_state); diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp new file mode 100644 index 0000000000..d7bde9a727 --- /dev/null +++ b/platform/haiku/key_mapping_haiku.cpp @@ -0,0 +1,193 @@ +#include + +#include "key_mapping_haiku.h" +#include "os/keyboard.h" + +struct _HaikuTranslatePair { + unsigned int keysym; + int32 keycode; +}; + +static _HaikuTranslatePair _mod_to_keycode[] = { + { KEY_SHIFT, B_SHIFT_KEY }, + { KEY_ALT, B_COMMAND_KEY }, + { KEY_CONTROL, B_CONTROL_KEY }, + { KEY_CAPSLOCK, B_CAPS_LOCK }, + { KEY_SCROLLLOCK, B_SCROLL_LOCK }, + { KEY_NUMLOCK, B_NUM_LOCK }, + { KEY_SUPER_L, B_OPTION_KEY }, + { KEY_MENU, B_MENU_KEY }, + { KEY_SHIFT, B_LEFT_SHIFT_KEY }, + { KEY_SHIFT, B_RIGHT_SHIFT_KEY }, + { KEY_ALT, B_LEFT_COMMAND_KEY }, + { KEY_ALT, B_RIGHT_COMMAND_KEY }, + { KEY_CONTROL, B_LEFT_CONTROL_KEY }, + { KEY_CONTROL, B_RIGHT_CONTROL_KEY }, + { KEY_SUPER_L, B_LEFT_OPTION_KEY }, + { KEY_SUPER_R, B_RIGHT_OPTION_KEY }, + { KEY_UNKNOWN, 0 } +}; + +static _HaikuTranslatePair _fn_to_keycode[] = { + { KEY_F1, B_F1_KEY }, + { KEY_F2, B_F2_KEY }, + { KEY_F3, B_F3_KEY }, + { KEY_F4, B_F4_KEY }, + { KEY_F5, B_F5_KEY }, + { KEY_F6, B_F6_KEY }, + { KEY_F7, B_F7_KEY }, + { KEY_F8, B_F8_KEY }, + { KEY_F9, B_F9_KEY }, + { KEY_F10, B_F10_KEY }, + { KEY_F11, B_F11_KEY }, + { KEY_F12, B_F12_KEY }, + //{ KEY_F13, ? }, + //{ KEY_F14, ? }, + //{ KEY_F15, ? }, + //{ KEY_F16, ? }, + { KEY_PRINT, B_PRINT_KEY }, + { KEY_SCROLLLOCK, B_SCROLL_KEY }, + { KEY_PAUSE, B_PAUSE_KEY }, + { KEY_UNKNOWN, 0 } +}; + +static _HaikuTranslatePair _hb_to_keycode[] = { + { KEY_BACKSPACE, B_BACKSPACE }, + { KEY_TAB, B_TAB }, + { KEY_RETURN, B_RETURN }, + { KEY_CAPSLOCK, B_CAPS_LOCK }, + { KEY_ESCAPE, B_ESCAPE }, + { KEY_SPACE, B_SPACE }, + { KEY_PAGEUP, B_PAGE_UP }, + { KEY_PAGEDOWN, B_PAGE_DOWN }, + { KEY_END, B_END }, + { KEY_HOME, B_HOME }, + { KEY_LEFT, B_LEFT_ARROW }, + { KEY_UP, B_UP_ARROW }, + { KEY_RIGHT, B_RIGHT_ARROW }, + { KEY_DOWN, B_DOWN_ARROW }, + { KEY_PRINT, B_PRINT_KEY }, + { KEY_INSERT, B_INSERT }, + { KEY_DELETE, B_DELETE }, + // { KEY_HELP, ??? }, + + { KEY_0, (0x30) }, + { KEY_1, (0x31) }, + { KEY_2, (0x32) }, + { KEY_3, (0x33) }, + { KEY_4, (0x34) }, + { KEY_5, (0x35) }, + { KEY_6, (0x36) }, + { KEY_7, (0x37) }, + { KEY_8, (0x38) }, + { KEY_9, (0x39) }, + { KEY_A, (0x61) }, + { KEY_B, (0x62) }, + { KEY_C, (0x63) }, + { KEY_D, (0x64) }, + { KEY_E, (0x65) }, + { KEY_F, (0x66) }, + { KEY_G, (0x67) }, + { KEY_H, (0x68) }, + { KEY_I, (0x69) }, + { KEY_J, (0x6A) }, + { KEY_K, (0x6B) }, + { KEY_L, (0x6C) }, + { KEY_M, (0x6D) }, + { KEY_N, (0x6E) }, + { KEY_O, (0x6F) }, + { KEY_P, (0x70) }, + { KEY_Q, (0x71) }, + { KEY_R, (0x72) }, + { KEY_S, (0x73) }, + { KEY_T, (0x74) }, + { KEY_U, (0x75) }, + { KEY_V, (0x76) }, + { KEY_W, (0x77) }, + { KEY_X, (0x78) }, + { KEY_Y, (0x79) }, + { KEY_Z, (0x7A) }, + +/* +{ KEY_PLAY, VK_PLAY},// (0xFA) +{ KEY_STANDBY,VK_SLEEP },//(0x5F) +{ KEY_BACK,VK_BROWSER_BACK},// (0xA6) +{ KEY_FORWARD,VK_BROWSER_FORWARD},// (0xA7) +{ KEY_REFRESH,VK_BROWSER_REFRESH},// (0xA8) +{ KEY_STOP,VK_BROWSER_STOP},// (0xA9) +{ KEY_SEARCH,VK_BROWSER_SEARCH},// (0xAA) +{ KEY_FAVORITES, VK_BROWSER_FAVORITES},// (0xAB) +{ KEY_HOMEPAGE,VK_BROWSER_HOME},// (0xAC) +{ KEY_VOLUMEMUTE,VK_VOLUME_MUTE},// (0xAD) +{ KEY_VOLUMEDOWN,VK_VOLUME_DOWN},// (0xAE) +{ KEY_VOLUMEUP,VK_VOLUME_UP},// (0xAF) +{ KEY_MEDIANEXT,VK_MEDIA_NEXT_TRACK},// (0xB0) +{ KEY_MEDIAPREVIOUS,VK_MEDIA_PREV_TRACK},// (0xB1) +{ KEY_MEDIASTOP,VK_MEDIA_STOP},// (0xB2) +{ KEY_LAUNCHMAIL, VK_LAUNCH_MAIL},// (0xB4) +{ KEY_LAUNCHMEDIA,VK_LAUNCH_MEDIA_SELECT},// (0xB5) +{ KEY_LAUNCH0,VK_LAUNCH_APP1},// (0xB6) +{ KEY_LAUNCH1,VK_LAUNCH_APP2},// (0xB7) +*/ + + { KEY_SEMICOLON, 0x3B }, + { KEY_EQUAL, 0x3D }, + { KEY_COLON, 0x2C }, + { KEY_MINUS, 0x2D }, + { KEY_PERIOD, 0x2E }, + { KEY_SLASH, 0x2F }, + { KEY_KP_MULTIPLY, 0x2A }, + { KEY_KP_ADD, 0x2B }, + + { KEY_QUOTELEFT, 0x60 }, + { KEY_BRACKETLEFT, 0x5B }, + { KEY_BACKSLASH, 0x5C }, + { KEY_BRACKETRIGHT, 0x5D }, + { KEY_APOSTROPHE, 0x27 }, + + { KEY_UNKNOWN, 0 } +}; + +unsigned int KeyMappingHaiku::get_keysym(int32 raw_char, int32 key) { + if (raw_char == B_INSERT && key == 0x64) { return KEY_KP_0; } + if (raw_char == B_END && key == 0x58) { return KEY_KP_1; } + if (raw_char == B_DOWN_ARROW && key == 0x59) { return KEY_KP_2; } + if (raw_char == B_PAGE_DOWN && key == 0x5A) { return KEY_KP_3; } + if (raw_char == B_LEFT_ARROW && key == 0x48) { return KEY_KP_4; } + if (raw_char == 0x35 && key == 0x49) { return KEY_KP_5; } + if (raw_char == B_RIGHT_ARROW && key == 0x4A) { return KEY_KP_6; } + if (raw_char == B_HOME && key == 0x37) { return KEY_KP_7; } + if (raw_char == B_UP_ARROW && key == 0x38) { return KEY_KP_8; } + if (raw_char == B_PAGE_UP && key == 0x39) { return KEY_KP_9; } + if (raw_char == 0x2F && key == 0x23) { return KEY_KP_DIVIDE; } + if (raw_char == 0x2D && key == 0x25) { return KEY_KP_SUBSTRACT; } + if (raw_char == B_DELETE && key == 0x65) { return KEY_KP_PERIOD; } + + if (raw_char == 0x10) { + for(int i = 0; _fn_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if (_fn_to_keycode[i].keycode == key) { + return _fn_to_keycode[i].keysym; + } + } + + return KEY_UNKNOWN; + } + + for(int i = 0; _hb_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if (_hb_to_keycode[i].keycode == raw_char) { + return _hb_to_keycode[i].keysym; + } + } + + return KEY_UNKNOWN; +} + +unsigned int KeyMappingHaiku::get_modifier_keysym(int32 key) { + for(int i = 0; _mod_to_keycode[i].keysym != KEY_UNKNOWN; i++) { + if ((_mod_to_keycode[i].keycode & key) != 0) { + return _mod_to_keycode[i].keysym; + } + } + + return KEY_UNKNOWN; +} diff --git a/platform/haiku/key_mapping_haiku.h b/platform/haiku/key_mapping_haiku.h new file mode 100644 index 0000000000..e2864678a8 --- /dev/null +++ b/platform/haiku/key_mapping_haiku.h @@ -0,0 +1,13 @@ +#ifndef KEY_MAPPING_HAIKU_H +#define KEY_MAPPING_HAIKU_H + +class KeyMappingHaiku +{ + KeyMappingHaiku() {}; + +public: + static unsigned int get_keysym(int32 raw_char, int32 key); + static unsigned int get_modifier_keysym(int32 key); +}; + +#endif -- cgit v1.2.3 From ec11762006e80105d24f3b1075b657e58f95e2ed Mon Sep 17 00:00:00 2001 From: MrGreenTea Date: Wed, 15 Jul 2015 01:59:35 +0200 Subject: added floor() and ceil() to Vector3 --- core/math/vector3.h | 30 +++++++++++++++++++++--------- core/variant_call.cpp | 18 ++++++++---------- 2 files changed, 29 insertions(+), 19 deletions(-) diff --git a/core/math/vector3.h b/core/math/vector3.h index d27b611379..8a3cca8f33 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -40,11 +40,11 @@ struct Vector3 { enum Axis { AXIS_X, AXIS_Y, - AXIS_Z, + AXIS_Z, }; union { - + #ifdef USE_QUAD_VECTORS struct { @@ -52,7 +52,7 @@ struct Vector3 { real_t y; real_t z; real_t _unused; - }; + }; real_t coord[4]; #else @@ -61,18 +61,18 @@ struct Vector3 { real_t y; real_t z; }; - + real_t coord[3]; #endif }; _FORCE_INLINE_ const real_t& operator[](int p_axis) const { - + return coord[p_axis]; } _FORCE_INLINE_ real_t& operator[](int p_axis) { - + return coord[p_axis]; } @@ -84,7 +84,7 @@ struct Vector3 { _FORCE_INLINE_ real_t length() const; _FORCE_INLINE_ real_t length_squared() const; - + _FORCE_INLINE_ void normalize(); _FORCE_INLINE_ Vector3 normalized() const; _FORCE_INLINE_ Vector3 inverse() const; @@ -107,6 +107,8 @@ struct Vector3 { _FORCE_INLINE_ real_t dot(const Vector3& p_b) const; _FORCE_INLINE_ Vector3 abs() const; + _FORCE_INLINE_ Vector3 floor() const; + _FORCE_INLINE_ Vector3 ceil() const; _FORCE_INLINE_ real_t distance_to(const Vector3& p_b) const; _FORCE_INLINE_ real_t distance_squared_to(const Vector3& p_b) const; @@ -172,7 +174,17 @@ real_t Vector3::dot(const Vector3& p_b) const { Vector3 Vector3::abs() const { return Vector3( Math::abs(x), Math::abs(y), Math::abs(z) ); -} +} + +Vector3 Vector3::floor() const { + + return Vector3( Math::floor(x), Math::floor(y), Math::floor(z) ); +} + +Vector3 Vector3::ceil() const { + + return Vector3( Math::ceil(x), Math::ceil(y), Math::ceil(z) ); +} Vector3 Vector3::linear_interpolate(const Vector3& p_b,float p_t) const { @@ -301,7 +313,7 @@ bool Vector3::operator<(const Vector3& p_v) const { return y *p_list) const { if (fd.returns) ret.name="ret"; mi.return_val=ret; -#endif +#endif p_list->push_back(mi); } @@ -1336,6 +1338,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(VECTOR3,REAL,Vector3,dot,VECTOR3,"b",varray()); ADDFUNC1(VECTOR3,VECTOR3,Vector3,cross,VECTOR3,"b",varray()); ADDFUNC0(VECTOR3,VECTOR3,Vector3,abs,varray()); + ADDFUNC0(VECTOR3,VECTOR3,Vector3,floor,varray()); + ADDFUNC0(VECTOR3,VECTOR3,Vector3,ceil,varray()); ADDFUNC1(VECTOR3,REAL,Vector3,distance_to,VECTOR3,"b",varray()); ADDFUNC1(VECTOR3,REAL,Vector3,distance_squared_to,VECTOR3,"b",varray()); ADDFUNC1(VECTOR3,VECTOR3,Vector3,slide,VECTOR3,"by",varray()); @@ -1535,10 +1539,10 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(TRANSFORM,NIL,Transform,xform,NIL,"v",varray()); ADDFUNC1(TRANSFORM,NIL,Transform,xform_inv,NIL,"v",varray()); -#ifdef DEBUG_ENABLED +#ifdef DEBUG_ENABLED _VariantCall::type_funcs[Variant::TRANSFORM].functions["xform"].returns=true; _VariantCall::type_funcs[Variant::TRANSFORM].functions["xform_inv"].returns=true; -#endif +#endif ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_pressed,varray()); ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action,STRING,"action",varray()); @@ -1635,9 +1639,3 @@ void unregister_variant_methods() { } - - - - - - -- cgit v1.2.3 From 5b71fc45b703d2ea44cc1aa99830ec3e0966b3e6 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Thu, 16 Jul 2015 22:38:12 -0300 Subject: Use popup menu to add new nodes to the shader graph editor in the last clicked location. --- scene/gui/graph_edit.cpp | 14 ++++++-- .../editor/plugins/shader_graph_editor_plugin.cpp | 37 ++++++++++++++-------- tools/editor/plugins/shader_graph_editor_plugin.h | 6 ++-- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 3cd0dd3d16..d0ff4e48d3 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -499,7 +499,15 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { if (p_ev.type==InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); - } + } else if (p_ev.type== InputEvent::MOUSE_BUTTON) { + + const InputEventMouseButton &b=p_ev.mouse_button; + + if (b.button_index==2 && b.pressed) + { + emit_signal("popup_request", Vector2(b.global_x, b.global_y)); + } + } } void GraphEdit::clear_connections() { @@ -554,8 +562,8 @@ void GraphEdit::_bind_methods() { ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event); ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); - ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); - + ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); + ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 03fcbffa24..b4fb14dbbc 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -2114,7 +2114,7 @@ void ShaderGraphView::_notification(int p_what) { } } -void ShaderGraphView::add_node(int p_type) { +void ShaderGraphView::add_node(int p_type, const Vector2 &location) { List existing; graph->get_node_list(type,&existing); @@ -2127,7 +2127,7 @@ void ShaderGraphView::add_node(int p_type) { } } - Vector2 init_ofs(20,20); + Vector2 init_ofs = location; while(true) { bool valid=true; for(List::Element *E=existing.front();E;E=E->next()) { @@ -2222,7 +2222,17 @@ void ShaderGraphEditor::_add_node(int p_type) { ShaderGraph::ShaderType shader_type=ShaderGraph::ShaderType(tabs->get_current_tab()); - graph_edits[shader_type]->add_node(p_type); + graph_edits[shader_type]->add_node(p_type, next_location); +} + +void ShaderGraphEditor::_popup_requested(const Vector2 &p_position) +{ + next_location = get_local_mouse_pos(); + popup->set_global_pos(p_position); + popup->set_size( Size2( 200, 0) ); + popup->popup(); + popup->call_deferred("grab_click_focus"); + popup->set_invalidate_click_until_motion(); } @@ -2243,11 +2253,11 @@ void ShaderGraphEditor::_notification(int p_what) { if (nn.ends_with(":")) { addsep=true; } - menu->get_popup()->add_icon_item(get_icon(ic,"EditorIcons"),v,i); + popup->add_icon_item(get_icon(ic,"EditorIcons"),v,i); if (addsep) - menu->get_popup()->add_separator(); + popup->add_separator(); } - menu->get_popup()->connect("item_pressed",this,"_add_node"); + popup->connect("item_pressed",this,"_add_node"); } @@ -2256,7 +2266,7 @@ void ShaderGraphEditor::_notification(int p_what) { void ShaderGraphEditor::_bind_methods() { ObjectTypeDB::bind_method("_add_node",&ShaderGraphEditor::_add_node); - + ObjectTypeDB::bind_method("_popup_requested",&ShaderGraphEditor::_popup_requested); } @@ -2302,11 +2312,10 @@ const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={ ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { _2d=p_2d; - HBoxContainer *hbc = memnew( HBoxContainer ); - menu = memnew( MenuButton ); - menu->set_text("Add Node.."); - hbc->add_child(menu); - add_child(hbc); + HBoxContainer *hbc = memnew( HBoxContainer ); + popup = memnew( PopupMenu ); + hbc->add_child(popup); + add_child(hbc); tabs = memnew(TabContainer); @@ -2325,8 +2334,8 @@ ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { tabs->add_child(graph_edits[i]->get_graph_edit()); graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); - graph_edits[i]->get_graph_edit()->set_right_disconnects(true); - + graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); + graph_edits[i]->get_graph_edit()->set_right_disconnects(true); } tabs->set_current_tab(1); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index 0051fbfd74..c41ec68360 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -175,7 +175,7 @@ protected: static void _bind_methods(); public: - void add_node(int p_type); + void add_node(int p_type, const Vector2 &location); GraphEdit *get_graph_edit() { return graph_edit; } void set_graph(Ref p_graph); @@ -186,13 +186,15 @@ class ShaderGraphEditor : public VBoxContainer { OBJ_TYPE(ShaderGraphEditor,VBoxContainer); - MenuButton *menu; + PopupMenu *popup; TabContainer *tabs; ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; + Vector2 next_location; bool _2d; void _add_node(int p_type); + void _popup_requested(const Vector2 &p_position); protected: void _notification(int p_what); static void _bind_methods(); -- cgit v1.2.3 From bdd12744fe340152cef5bf88de9e2d183bff1790 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sun, 19 Jul 2015 01:48:46 -0300 Subject: Select and move multiple nodes at once --- scene/gui/graph_edit.cpp | 861 +++-- scene/gui/graph_edit.h | 106 +- scene/gui/graph_node.cpp | 686 ++-- scene/gui/graph_node.h | 125 +- scene/resources/default_theme/default_theme.cpp | 2 + .../default_theme/graph_node_selected.png | Bin 0 -> 738 bytes scene/resources/default_theme/theme_data.h | 5 + .../editor/plugins/shader_graph_editor_plugin.cpp | 3779 ++++++++++---------- tools/editor/plugins/shader_graph_editor_plugin.h | 244 +- 9 files changed, 2966 insertions(+), 2842 deletions(-) create mode 100644 scene/resources/default_theme/graph_node_selected.png diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index d0ff4e48d3..4569c71d0b 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -3,388 +3,385 @@ #include "os/keyboard.h" bool GraphEditFilter::has_point(const Point2& p_point) const { - return ge->_filter_input(p_point); + return ge->_filter_input(p_point); } GraphEditFilter::GraphEditFilter(GraphEdit *p_edit) { - ge=p_edit; + ge=p_edit; } Error GraphEdit::connect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port) { - if (is_node_connected(p_from,p_from_port,p_to,p_to_port)) - return OK; - Connection c; - c.from=p_from; - c.from_port=p_from_port; - c.to=p_to; - c.to_port=p_to_port; - connections.push_back(c); - top_layer->update(); - - return OK; + if (is_node_connected(p_from,p_from_port,p_to,p_to_port)) + return OK; + Connection c; + c.from=p_from; + c.from_port=p_from_port; + c.to=p_to; + c.to_port=p_to_port; + connections.push_back(c); + top_layer->update(); + + return OK; } bool GraphEdit::is_node_connected(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port) { - for(List::Element *E=connections.front();E;E=E->next()) { + for(List::Element *E=connections.front();E;E=E->next()) { - if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) - return true; - } + if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) + return true; + } - return false; + return false; } void GraphEdit::disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port){ - for(List::Element *E=connections.front();E;E=E->next()) { + for(List::Element *E=connections.front();E;E=E->next()) { - if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) { + if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) { - connections.erase(E); - top_layer->update(); - return; - } - } + connections.erase(E); + top_layer->update(); + return; + } + } } void GraphEdit::get_connection_list(List *r_connections) const { - *r_connections=connections; + *r_connections=connections; } void GraphEdit::_scroll_moved(double) { - _update_scroll_offset(); - top_layer->update(); + _update_scroll_offset(); + top_layer->update(); } void GraphEdit::_update_scroll_offset() { - for(int i=0;icast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - Point2 pos=gn->get_offset(); - pos-=Point2(h_scroll->get_val(),v_scroll->get_val()); - gn->set_pos(pos); - } + Point2 pos=gn->get_offset(); + pos-=Point2(h_scroll->get_val(),v_scroll->get_val()); + gn->set_pos(pos); + } } void GraphEdit::_update_scroll() { - if (updating) - return; + if (updating) + return; - updating=true; - Rect2 screen; - for(int i=0;icast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - Rect2 r; - r.pos=gn->get_offset(); - r.size=gn->get_size(); - screen = screen.merge(r); - } + Rect2 r; + r.pos=gn->get_offset(); + r.size=gn->get_size(); + screen = screen.merge(r); + } - screen.pos-=get_size(); - screen.size+=get_size()*2.0; + screen.pos-=get_size(); + screen.size+=get_size()*2.0; - h_scroll->set_min(screen.pos.x); - h_scroll->set_max(screen.pos.x+screen.size.x); - h_scroll->set_page(get_size().x); - if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) - h_scroll->hide(); - else - h_scroll->show(); + h_scroll->set_min(screen.pos.x); + h_scroll->set_max(screen.pos.x+screen.size.x); + h_scroll->set_page(get_size().x); + if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) + h_scroll->hide(); + else + h_scroll->show(); - v_scroll->set_min(screen.pos.y); - v_scroll->set_max(screen.pos.y+screen.size.y); - v_scroll->set_page(get_size().y); + v_scroll->set_min(screen.pos.y); + v_scroll->set_max(screen.pos.y+screen.size.y); + v_scroll->set_page(get_size().y); - if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) - v_scroll->hide(); - else - v_scroll->show(); + if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) + v_scroll->hide(); + else + v_scroll->show(); - _update_scroll_offset(); - updating=false; + _update_scroll_offset(); + updating=false; } void GraphEdit::_graph_node_raised(Node* p_gn) { - GraphNode *gn=p_gn->cast_to(); - ERR_FAIL_COND(!gn); - gn->raise(); - top_layer->raise(); + GraphNode *gn=p_gn->cast_to(); + ERR_FAIL_COND(!gn); + gn->raise(); + top_layer->raise(); } void GraphEdit::_graph_node_moved(Node *p_gn) { - GraphNode *gn=p_gn->cast_to(); - ERR_FAIL_COND(!gn); - - //gn->set_pos(gn->get_offset()+scroll_offset); - - top_layer->update(); + GraphNode *gn=p_gn->cast_to(); + ERR_FAIL_COND(!gn); + top_layer->update(); } void GraphEdit::add_child_notify(Node *p_child) { - top_layer->call_deferred("raise"); //top layer always on top! - GraphNode *gn = p_child->cast_to(); - if (gn) { - gn->connect("offset_changed",this,"_graph_node_moved",varray(gn)); - gn->connect("raise_request",this,"_graph_node_raised",varray(gn)); - _graph_node_moved(gn); - gn->set_stop_mouse(false); - } + top_layer->call_deferred("raise"); //top layer always on top! + GraphNode *gn = p_child->cast_to(); + if (gn) { + gn->connect("offset_changed",this,"_graph_node_moved",varray(gn)); + gn->connect("raise_request",this,"_graph_node_raised",varray(gn)); + _graph_node_moved(gn); + gn->set_stop_mouse(false); + } } void GraphEdit::remove_child_notify(Node *p_child) { - top_layer->call_deferred("raise"); //top layer always on top! - GraphNode *gn = p_child->cast_to(); - if (gn) { - gn->disconnect("offset_changed",this,"_graph_node_moved"); - gn->disconnect("raise_request",this,"_graph_node_raised"); - } + top_layer->call_deferred("raise"); //top layer always on top! + GraphNode *gn = p_child->cast_to(); + if (gn) { + gn->disconnect("offset_changed",this,"_graph_node_moved"); + gn->disconnect("raise_request",this,"_graph_node_raised"); + } } void GraphEdit::_notification(int p_what) { - if (p_what==NOTIFICATION_READY) { - Size2 size = top_layer->get_size(); - Size2 hmin = h_scroll->get_combined_minimum_size(); - Size2 vmin = v_scroll->get_combined_minimum_size(); + if (p_what==NOTIFICATION_READY) { + Size2 size = top_layer->get_size(); + Size2 hmin = h_scroll->get_combined_minimum_size(); + Size2 vmin = v_scroll->get_combined_minimum_size(); - v_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,vmin.width); - v_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); - v_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,0); - v_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); + v_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,vmin.width); + v_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); + v_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,0); + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); - h_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,0); - h_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); - h_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,hmin.height); - h_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); + h_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,0); + h_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); + h_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,hmin.height); + h_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); - } - if (p_what==NOTIFICATION_DRAW) { - VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); + } + if (p_what==NOTIFICATION_DRAW) { + VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); - } + } - if (p_what==NOTIFICATION_RESIZED) { - _update_scroll(); - top_layer->update(); - } + if (p_what==NOTIFICATION_RESIZED) { + _update_scroll(); + top_layer->update(); + } } bool GraphEdit::_filter_input(const Point2& p_point) { - Ref port =get_icon("port","GraphNode"); + Ref port =get_icon("port","GraphNode"); - float grab_r=port->get_width()*0.5; - for(int i=get_child_count()-1;i>=0;i--) { + float grab_r=port->get_width()*0.5; + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - for(int j=0;jget_connection_output_count();j++) { + for(int j=0;jget_connection_output_count();j++) { - Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); - if (pos.distance_to(p_point)get_connection_output_pos(j)+gn->get_pos(); + if (pos.distance_to(p_point)get_connection_input_count();j++) { + for(int j=0;jget_connection_input_count();j++) { - Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); - if (pos.distance_to(p_point)get_connection_input_pos(j)+gn->get_pos(); + if (pos.distance_to(p_point) port =get_icon("port","GraphNode"); - Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); - float grab_r=port->get_width()*0.5; - for(int i=get_child_count()-1;i>=0;i--) { + Ref port =get_icon("port","GraphNode"); + Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); + float grab_r=port->get_width()*0.5; + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - for(int j=0;jget_connection_output_count();j++) { + for(int j=0;jget_connection_output_count();j++) { - Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); - if (pos.distance_to(mpos)get_connection_output_pos(j)+gn->get_pos(); + if (pos.distance_to(mpos)get_name(); - connecting_index=j; - connecting_out=true; - connecting_type=gn->get_connection_output_type(j); - connecting_color=gn->get_connection_output_color(j); - connecting_target=false; - connecting_to=pos; - return; - } + connecting=true; + connecting_from=gn->get_name(); + connecting_index=j; + connecting_out=true; + connecting_type=gn->get_connection_output_type(j); + connecting_color=gn->get_connection_output_color(j); + connecting_target=false; + connecting_to=pos; + return; + } - } + } - for(int j=0;jget_connection_input_count();j++) { + for(int j=0;jget_connection_input_count();j++) { - Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); + Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); - if (pos.distance_to(mpos)::Element*E=connections.front();E;E=E->next()) { + if (right_disconnects) { + //check disconnect + for (List::Element*E=connections.front();E;E=E->next()) { - if (E->get().to==gn->get_name() && E->get().to_port==j) { + if (E->get().to==gn->get_name() && E->get().to_port==j) { - Node*fr = get_node(String(E->get().from)); - if (fr && fr->cast_to()) { + Node*fr = get_node(String(E->get().from)); + if (fr && fr->cast_to()) { - connecting_from=E->get().from; - connecting_index=E->get().from_port; - connecting_out=true; - connecting_type=fr->cast_to()->get_connection_output_type(E->get().from_port); - connecting_color=fr->cast_to()->get_connection_output_color(E->get().from_port); - connecting_target=false; - connecting_to=pos; + connecting_from=E->get().from; + connecting_index=E->get().from_port; + connecting_out=true; + connecting_type=fr->cast_to()->get_connection_output_type(E->get().from_port); + connecting_color=fr->cast_to()->get_connection_output_color(E->get().from_port); + connecting_target=false; + connecting_to=pos; - emit_signal("disconnection_request",E->get().from,E->get().from_port,E->get().to,E->get().to_port); - fr = get_node(String(connecting_from)); //maybe it was erased - if (fr && fr->cast_to()) { - connecting=true; - } - return; - } + emit_signal("disconnection_request",E->get().from,E->get().from_port,E->get().to,E->get().to_port); + fr = get_node(String(connecting_from)); //maybe it was erased + if (fr && fr->cast_to()) { + connecting=true; + } + return; + } - } - } - } + } + } + } - connecting=true; - connecting_from=gn->get_name(); - connecting_index=j; - connecting_out=false; - connecting_type=gn->get_connection_input_type(j); - connecting_color=gn->get_connection_input_color(j); - connecting_target=false; - connecting_to=pos; - return; - } + connecting=true; + connecting_from=gn->get_name(); + connecting_index=j; + connecting_out=false; + connecting_type=gn->get_connection_input_type(j); + connecting_color=gn->get_connection_input_color(j); + connecting_target=false; + connecting_to=pos; + return; + } - } - } - } + } + } + } - if (p_ev.type==InputEvent::MOUSE_MOTION && connecting) { + if (p_ev.type==InputEvent::MOUSE_MOTION && connecting) { - connecting_to=Vector2(p_ev.mouse_motion.x,p_ev.mouse_motion.y); - connecting_target=false; - top_layer->update(); + connecting_to=Vector2(p_ev.mouse_motion.x,p_ev.mouse_motion.y); + connecting_target=false; + top_layer->update(); - Ref port =get_icon("port","GraphNode"); - Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); - float grab_r=port->get_width()*0.5; - for(int i=get_child_count()-1;i>=0;i--) { + Ref port =get_icon("port","GraphNode"); + Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); + float grab_r=port->get_width()*0.5; + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - if (!connecting_out) { - for(int j=0;jget_connection_output_count();j++) { + if (!connecting_out) { + for(int j=0;jget_connection_output_count();j++) { - Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); - int type =gn->get_connection_output_type(j); - if (type==connecting_type && pos.distance_to(mpos)get_connection_output_pos(j)+gn->get_pos(); + int type =gn->get_connection_output_type(j); + if (type==connecting_type && pos.distance_to(mpos)get_name(); - connecting_target_index=j; - return; - } + connecting_target=true; + connecting_to=pos; + connecting_target_to=gn->get_name(); + connecting_target_index=j; + return; + } - } - } else { + } + } else { - for(int j=0;jget_connection_input_count();j++) { + for(int j=0;jget_connection_input_count();j++) { - Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); - int type =gn->get_connection_input_type(j); - if (type==connecting_type && pos.distance_to(mpos)get_name(); - connecting_target_index=j; - return; - } - } - } - } - } + Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); + int type =gn->get_connection_input_type(j); + if (type==connecting_type && pos.distance_to(mpos)get_name(); + connecting_target_index=j; + return; + } + } + } + } + } - if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index==BUTTON_LEFT && !p_ev.mouse_button.pressed) { + if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index==BUTTON_LEFT && !p_ev.mouse_button.pressed) { - if (connecting && connecting_target) { + if (connecting && connecting_target) { - String from = connecting_from; - int from_slot = connecting_index; - String to =connecting_target_to; - int to_slot = connecting_target_index; + String from = connecting_from; + int from_slot = connecting_index; + String to =connecting_target_to; + int to_slot = connecting_target_index; - if (!connecting_out) { - SWAP(from,to); - SWAP(from_slot,to_slot); - } - emit_signal("connection_request",from,from_slot,to,to_slot); - - } - connecting=false; - top_layer->update(); + if (!connecting_out) { + SWAP(from,to); + SWAP(from_slot,to_slot); + } + emit_signal("connection_request",from,from_slot,to,to_slot); - } + } + connecting=false; + top_layer->update(); + + } @@ -392,203 +389,295 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { void GraphEdit::_draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color) { - static const int steps = 20; + static const int steps = 20; - Rect2 r; - r.pos=p_from; - r.expand_to(p_to); - Vector2 sign=Vector2((p_from.x < p_to.x) ? 1 : -1,(p_from.y < p_to.y) ? 1 : -1); - bool flip = sign.x * sign.y < 0; + Rect2 r; + r.pos=p_from; + r.expand_to(p_to); + Vector2 sign=Vector2((p_from.x < p_to.x) ? 1 : -1,(p_from.y < p_to.y) ? 1 : -1); + bool flip = sign.x * sign.y < 0; - Vector2 prev; - for(int i=0;i<=steps;i++) { + Vector2 prev; + for(int i=0;i<=steps;i++) { - float d = i/float(steps); - float c=-Math::cos(d*Math_PI) * 0.5+0.5; - if (flip) - c=1.0-c; - Vector2 p = r.pos+Vector2(d*r.size.width,c*r.size.height); + float d = i/float(steps); + float c=-Math::cos(d*Math_PI) * 0.5+0.5; + if (flip) + c=1.0-c; + Vector2 p = r.pos+Vector2(d*r.size.width,c*r.size.height); - if (i>0) { + if (i>0) { - top_layer->draw_line(prev,p,p_color,2); - } + top_layer->draw_line(prev,p,p_color,2); + } - prev=p; - } + prev=p; + } } void GraphEdit::_top_layer_draw() { - _update_scroll(); - - if (connecting) { - - Node *fromn = get_node(connecting_from); - ERR_FAIL_COND(!fromn); - GraphNode *from = fromn->cast_to(); - ERR_FAIL_COND(!from); - Vector2 pos; - if (connecting_out) - pos=from->get_connection_output_pos(connecting_index); - else - pos=from->get_connection_input_pos(connecting_index); - pos+=from->get_pos(); - - Vector2 topos; - topos=connecting_to; - - Color col=connecting_color; - - if (connecting_target) { - col.r+=0.4; - col.g+=0.4; - col.b+=0.4; - } - _draw_cos_line(pos,topos,col); - } - - List::Element* > to_erase; - for(List::Element *E=connections.front();E;E=E->next()) { - - NodePath fromnp(E->get().from); - - Node * from = get_node(fromnp); - if (!from) { - to_erase.push_back(E); - continue; - } - - GraphNode *gfrom = from->cast_to(); - - if (!gfrom) { - to_erase.push_back(E); - continue; - } - - NodePath tonp(E->get().to); - Node * to = get_node(tonp); - if (!to) { - to_erase.push_back(E); - continue; - } - - GraphNode *gto = to->cast_to(); - - if (!gto) { - to_erase.push_back(E); - continue; - } - - Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos(); - Color color = gfrom->get_connection_output_color(E->get().from_port); - Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos(); - _draw_cos_line(frompos,topos,color); - - } - - while(to_erase.size()) { - connections.erase(to_erase.front()->get()); - to_erase.pop_front(); - } - //draw connections + _update_scroll(); + + if (connecting) { + + Node *fromn = get_node(connecting_from); + ERR_FAIL_COND(!fromn); + GraphNode *from = fromn->cast_to(); + ERR_FAIL_COND(!from); + Vector2 pos; + if (connecting_out) + pos=from->get_connection_output_pos(connecting_index); + else + pos=from->get_connection_input_pos(connecting_index); + pos+=from->get_pos(); + + Vector2 topos; + topos=connecting_to; + + Color col=connecting_color; + + if (connecting_target) { + col.r+=0.4; + col.g+=0.4; + col.b+=0.4; + } + _draw_cos_line(pos,topos,col); + } + + List::Element* > to_erase; + for(List::Element *E=connections.front();E;E=E->next()) { + + NodePath fromnp(E->get().from); + + Node * from = get_node(fromnp); + if (!from) { + to_erase.push_back(E); + continue; + } + + GraphNode *gfrom = from->cast_to(); + + if (!gfrom) { + to_erase.push_back(E); + continue; + } + + NodePath tonp(E->get().to); + Node * to = get_node(tonp); + if (!to) { + to_erase.push_back(E); + continue; + } + + GraphNode *gto = to->cast_to(); + + if (!gto) { + to_erase.push_back(E); + continue; + } + + Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos(); + Color color = gfrom->get_connection_output_color(E->get().from_port); + Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos(); + _draw_cos_line(frompos,topos,color); + + } + + while(to_erase.size()) { + connections.erase(to_erase.front()->get()); + to_erase.pop_front(); + } + //draw connections } void GraphEdit::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { - h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); - v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); - } else if (p_ev.type== InputEvent::MOUSE_BUTTON) { + if (p_ev.type==InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { + h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); + v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); + } + + if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { + + just_selected=true; + drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); + for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn=get_child(i)->cast_to(); + if (gn && gn->is_selected()) + gn->set_offset(gn->get_drag_from()+drag_accum); + } + } + + if (p_ev.type== InputEvent::MOUSE_BUTTON) { const InputEventMouseButton &b=p_ev.mouse_button; - if (b.button_index==2 && b.pressed) + if (b.button_index==BUTTON_RIGHT && b.pressed) { emit_signal("popup_request", Vector2(b.global_x, b.global_y)); } + + if (b.button_index==BUTTON_LEFT && !b.pressed && dragging) { + if (!just_selected && drag_accum==Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + //deselect current node + for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn=get_child(i)->cast_to(); + + if (gn && gn->get_rect().has_point(get_local_mouse_pos())) + gn->set_selected(false); + } + } + + if (drag_accum!=Vector2()) { + + emit_signal("_begin_node_move"); + + for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn=get_child(i)->cast_to(); + if (gn && gn->is_selected()) + gn->set_drag(false); + } + + emit_signal("_end_node_move"); + } + + dragging = false; + + top_layer->update(); + } + + if (b.button_index==BUTTON_LEFT && b.pressed) { + + GraphNode *gn; + for(int i=get_child_count()-1;i>=0;i--) { + + gn=get_child(i)->cast_to(); + + if (gn && gn->get_rect().has_point(get_local_mouse_pos())) + break; + } + + if (gn) { + + if (_filter_input(Vector2(b.x,b.y))) + return; + + dragging = true; + drag_accum = Vector2(); + just_selected = !gn->is_selected(); + if(!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + for (int i = 0; i < get_child_count(); i++) { + GraphNode *o_gn = get_child(i)->cast_to(); + if (o_gn) + o_gn->set_selected(o_gn == gn); + } + } + + gn->set_selected(true); + for (int i = 0; i < get_child_count(); i++) { + GraphNode *o_gn = get_child(i)->cast_to(); + if (!o_gn) + continue; + if (o_gn->is_selected()) + o_gn->set_drag(true); + } + + } else { + for(int i=get_child_count()-1;i>=0;i--) { + + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; + + gn->set_selected(false); + } + } + } } } void GraphEdit::clear_connections() { - connections.clear(); - update(); + connections.clear(); + update(); } void GraphEdit::set_right_disconnects(bool p_enable) { - right_disconnects=p_enable; + right_disconnects=p_enable; } bool GraphEdit::is_right_disconnects_enabled() const{ - return right_disconnects; + return right_disconnects; } Array GraphEdit::_get_connection_list() const { - List conns; - get_connection_list(&conns); - Array arr; - for(List::Element *E=conns.front();E;E=E->next()) { - Dictionary d; - d["from"]=E->get().from; - d["from_port"]=E->get().from_port; - d["to"]=E->get().to; - d["to_port"]=E->get().to_port; - arr.push_back(d); - } - return arr; + List conns; + get_connection_list(&conns); + Array arr; + for(List::Element *E=conns.front();E;E=E->next()) { + Dictionary d; + d["from"]=E->get().from; + d["from_port"]=E->get().from_port; + d["to"]=E->get().to; + d["to_port"]=E->get().to_port; + arr.push_back(d); + } + return arr; } void GraphEdit::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node); - ObjectTypeDB::bind_method(_MD("is_node_connected","from","from_port","to","to_port"),&GraphEdit::is_node_connected); - ObjectTypeDB::bind_method(_MD("disconnect_node","from","from_port","to","to_port"),&GraphEdit::disconnect_node); - ObjectTypeDB::bind_method(_MD("get_connection_list"),&GraphEdit::_get_connection_list); + ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node); + ObjectTypeDB::bind_method(_MD("is_node_connected","from","from_port","to","to_port"),&GraphEdit::is_node_connected); + ObjectTypeDB::bind_method(_MD("disconnect_node","from","from_port","to","to_port"),&GraphEdit::disconnect_node); + ObjectTypeDB::bind_method(_MD("get_connection_list"),&GraphEdit::_get_connection_list); - ObjectTypeDB::bind_method(_MD("set_right_disconnects","enable"),&GraphEdit::set_right_disconnects); - ObjectTypeDB::bind_method(_MD("is_right_disconnects_enabled"),&GraphEdit::is_right_disconnects_enabled); + ObjectTypeDB::bind_method(_MD("set_right_disconnects","enable"),&GraphEdit::set_right_disconnects); + ObjectTypeDB::bind_method(_MD("is_right_disconnects_enabled"),&GraphEdit::is_right_disconnects_enabled); - ObjectTypeDB::bind_method(_MD("_graph_node_moved"),&GraphEdit::_graph_node_moved); - ObjectTypeDB::bind_method(_MD("_graph_node_raised"),&GraphEdit::_graph_node_raised); + ObjectTypeDB::bind_method(_MD("_graph_node_moved"),&GraphEdit::_graph_node_moved); + ObjectTypeDB::bind_method(_MD("_graph_node_raised"),&GraphEdit::_graph_node_raised); - ObjectTypeDB::bind_method(_MD("_top_layer_input"),&GraphEdit::_top_layer_input); - ObjectTypeDB::bind_method(_MD("_top_layer_draw"),&GraphEdit::_top_layer_draw); - ObjectTypeDB::bind_method(_MD("_scroll_moved"),&GraphEdit::_scroll_moved); + ObjectTypeDB::bind_method(_MD("_top_layer_input"),&GraphEdit::_top_layer_input); + ObjectTypeDB::bind_method(_MD("_top_layer_draw"),&GraphEdit::_top_layer_draw); + ObjectTypeDB::bind_method(_MD("_scroll_moved"),&GraphEdit::_scroll_moved); - ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event); + ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event); - ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); + ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); + ADD_SIGNAL(MethodInfo("_begin_node_move")); + ADD_SIGNAL(MethodInfo("_end_node_move")); } GraphEdit::GraphEdit() { - top_layer=NULL; - top_layer=memnew(GraphEditFilter(this)); - add_child(top_layer); - top_layer->set_stop_mouse(false); - top_layer->set_area_as_parent_rect(); - top_layer->connect("draw",this,"_top_layer_draw"); + top_layer=NULL; + top_layer=memnew(GraphEditFilter(this)); + add_child(top_layer); + top_layer->set_stop_mouse(false); + top_layer->set_area_as_parent_rect(); + top_layer->connect("draw",this,"_top_layer_draw"); top_layer->set_stop_mouse(false); - top_layer->connect("input_event",this,"_top_layer_input"); + top_layer->connect("input_event",this,"_top_layer_input"); - h_scroll = memnew(HScrollBar); - h_scroll->set_name("_h_scroll"); - top_layer->add_child(h_scroll); + h_scroll = memnew(HScrollBar); + h_scroll->set_name("_h_scroll"); + top_layer->add_child(h_scroll); - v_scroll = memnew(VScrollBar); - v_scroll->set_name("_v_scroll"); - top_layer->add_child(v_scroll); - updating=false; - connecting=false; - right_disconnects=false; + v_scroll = memnew(VScrollBar); + v_scroll->set_name("_v_scroll"); + top_layer->add_child(v_scroll); + updating=false; + connecting=false; + right_disconnects=false; - h_scroll->connect("value_changed", this,"_scroll_moved"); - v_scroll->connect("value_changed", this,"_scroll_moved"); + h_scroll->connect("value_changed", this,"_scroll_moved"); + v_scroll->connect("value_changed", this,"_scroll_moved"); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 0a9da73ab6..2f9a5fc954 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -8,93 +8,95 @@ class GraphEdit; class GraphEditFilter : public Control { - OBJ_TYPE(GraphEditFilter,Control); + OBJ_TYPE(GraphEditFilter,Control); friend class GraphEdit; - GraphEdit *ge; - virtual bool has_point(const Point2& p_point) const; + GraphEdit *ge; + virtual bool has_point(const Point2& p_point) const; public: - GraphEditFilter(GraphEdit *p_edit); + GraphEditFilter(GraphEdit *p_edit); }; class GraphEdit : public Control { - OBJ_TYPE(GraphEdit,Control); + OBJ_TYPE(GraphEdit,Control); public: - struct Connection { - StringName from; - StringName to; - int from_port; - int to_port; + struct Connection { + StringName from; + StringName to; + int from_port; + int to_port; - }; + }; private: - HScrollBar* h_scroll; - VScrollBar* v_scroll; + HScrollBar* h_scroll; + VScrollBar* v_scroll; - bool connecting; - String connecting_from; - bool connecting_out; - int connecting_index; - int connecting_type; - Color connecting_color; - bool connecting_target; - Vector2 connecting_to; - String connecting_target_to; - int connecting_target_index; + bool connecting; + String connecting_from; + bool connecting_out; + int connecting_index; + int connecting_type; + Color connecting_color; + bool connecting_target; + Vector2 connecting_to; + String connecting_target_to; + int connecting_target_index; + bool dragging; + bool just_selected; + Vector2 drag_accum; + bool right_disconnects; + bool updating; + List connections; - bool right_disconnects; - bool updating; - List connections; + void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); - void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); + void _graph_node_raised(Node* p_gn); + void _graph_node_moved(Node *p_gn); - void _graph_node_raised(Node* p_gn); - void _graph_node_moved(Node *p_gn); + void _update_scroll(); + void _scroll_moved(double); + void _input_event(const InputEvent& p_ev); - void _update_scroll(); - void _scroll_moved(double); - void _input_event(const InputEvent& p_ev); + GraphEditFilter *top_layer; + void _top_layer_input(const InputEvent& p_ev); + void _top_layer_draw(); + void _update_scroll_offset(); - GraphEditFilter *top_layer; - void _top_layer_input(const InputEvent& p_ev); - void _top_layer_draw(); - void _update_scroll_offset(); - - Array _get_connection_list() const; + Array _get_connection_list() const; friend class GraphEditFilter; - bool _filter_input(const Point2& p_point); + bool _filter_input(const Point2& p_point); protected: - static void _bind_methods(); - virtual void add_child_notify(Node *p_child); - virtual void remove_child_notify(Node *p_child); - void _notification(int p_what); + static void _bind_methods(); + virtual void add_child_notify(Node *p_child); + virtual void remove_child_notify(Node *p_child); + void _notification(int p_what); public: - Error connect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); - bool is_node_connected(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); - void disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); - void clear_connections(); + Error connect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); + bool is_node_connected(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); + void disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); + void clear_connections(); - GraphEditFilter *get_top_layer() const { return top_layer; } - void get_connection_list(List *r_connections) const; + GraphEditFilter *get_top_layer() const { return top_layer; } + void get_connection_list(List *r_connections) const; - void set_right_disconnects(bool p_enable); - bool is_right_disconnects_enabled() const; + void set_right_disconnects(bool p_enable); + bool is_right_disconnects_enabled() const; - GraphEdit(); + GraphEdit(); }; #endif // GRAPHEdit_H diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 444b37855f..760eb6ceed 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -4,91 +4,91 @@ bool GraphNode::_set(const StringName& p_name, const Variant& p_value) { - if (!p_name.operator String().begins_with("slot/")) - return false; + if (!p_name.operator String().begins_with("slot/")) + return false; - int idx=p_name.operator String().get_slice("/",1).to_int(); - String what = p_name.operator String().get_slice("/",2); + int idx=p_name.operator String().get_slice("/",1).to_int(); + String what = p_name.operator String().get_slice("/",2); - Slot si; - if (slot_info.has(idx)) - si=slot_info[idx]; + Slot si; + if (slot_info.has(idx)) + si=slot_info[idx]; - if (what=="left_enabled") - si.enable_left=p_value; - else if (what=="left_type") - si.type_left=p_value; - else if (what=="left_color") - si.color_left=p_value; - else if (what=="right_enabled") - si.enable_right=p_value; - else if (what=="right_type") - si.type_right=p_value; - else if (what=="right_color") - si.color_right=p_value; - else - return false; + if (what=="left_enabled") + si.enable_left=p_value; + else if (what=="left_type") + si.type_left=p_value; + else if (what=="left_color") + si.color_left=p_value; + else if (what=="right_enabled") + si.enable_right=p_value; + else if (what=="right_type") + si.type_right=p_value; + else if (what=="right_color") + si.color_right=p_value; + else + return false; - set_slot(idx,si.enable_left,si.type_left,si.color_left,si.enable_right,si.type_right,si.color_right); - update(); - return true; + set_slot(idx,si.enable_left,si.type_left,si.color_left,si.enable_right,si.type_right,si.color_right); + update(); + return true; } bool GraphNode::_get(const StringName& p_name,Variant &r_ret) const{ - if (!p_name.operator String().begins_with("slot/")) { - return false; - } + if (!p_name.operator String().begins_with("slot/")) { + return false; + } - int idx=p_name.operator String().get_slice("/",1).to_int(); - String what = p_name.operator String().get_slice("/",2); + int idx=p_name.operator String().get_slice("/",1).to_int(); + String what = p_name.operator String().get_slice("/",2); - Slot si; - if (slot_info.has(idx)) - si=slot_info[idx]; + Slot si; + if (slot_info.has(idx)) + si=slot_info[idx]; - if (what=="left_enabled") - r_ret=si.enable_left; - else if (what=="left_type") - r_ret=si.type_left; - else if (what=="left_color") - r_ret=si.color_left; - else if (what=="right_enabled") - r_ret=si.enable_right; - else if (what=="right_type") - r_ret=si.type_right; - else if (what=="right_color") - r_ret=si.color_right; - else - return false; + if (what=="left_enabled") + r_ret=si.enable_left; + else if (what=="left_type") + r_ret=si.type_left; + else if (what=="left_color") + r_ret=si.color_left; + else if (what=="right_enabled") + r_ret=si.enable_right; + else if (what=="right_type") + r_ret=si.type_right; + else if (what=="right_color") + r_ret=si.color_right; + else + return false; - return true; + return true; } void GraphNode::_get_property_list( List *p_list) const{ - int idx=0; - for(int i=0;icast_to(); - if (!c || c->is_set_as_toplevel() ) - continue; + int idx=0; + for(int i=0;icast_to(); + if (!c || c->is_set_as_toplevel() ) + continue; - String base="slot/"+itos(idx)+"/"; + String base="slot/"+itos(idx)+"/"; - p_list->push_back(PropertyInfo(Variant::BOOL,base+"left_enabled")); - p_list->push_back(PropertyInfo(Variant::INT,base+"left_type")); - p_list->push_back(PropertyInfo(Variant::COLOR,base+"left_color")); - p_list->push_back(PropertyInfo(Variant::BOOL,base+"right_enabled")); - p_list->push_back(PropertyInfo(Variant::INT,base+"right_type")); - p_list->push_back(PropertyInfo(Variant::COLOR,base+"right_color")); + p_list->push_back(PropertyInfo(Variant::BOOL,base+"left_enabled")); + p_list->push_back(PropertyInfo(Variant::INT,base+"left_type")); + p_list->push_back(PropertyInfo(Variant::COLOR,base+"left_color")); + p_list->push_back(PropertyInfo(Variant::BOOL,base+"right_enabled")); + p_list->push_back(PropertyInfo(Variant::INT,base+"right_type")); + p_list->push_back(PropertyInfo(Variant::COLOR,base+"right_color")); - idx++; - } + idx++; + } } @@ -96,61 +96,61 @@ void GraphNode::_resort() { - int sep=get_constant("separation"); - Ref sb=get_stylebox("frame"); - bool first=true; + int sep=get_constant("separation"); + Ref sb=get_stylebox("frame"); + bool first=true; - Size2 minsize; + Size2 minsize; - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + for(int i=0;icast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - minsize.y+=size.y; - minsize.x=MAX(minsize.x,size.x); + minsize.y+=size.y; + minsize.x=MAX(minsize.x,size.x); - if (first) - first=false; - else - minsize.y+=sep; + if (first) + first=false; + else + minsize.y+=sep; - } + } - int vofs=0; - int w = get_size().x - sb->get_minimum_size().x; + int vofs=0; + int w = get_size().x - sb->get_minimum_size().x; - cache_y.clear(); - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + cache_y.clear(); + for(int i=0;icast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - Rect2 r(sb->get_margin(MARGIN_LEFT),sb->get_margin(MARGIN_TOP)+vofs,w,size.y); + Rect2 r(sb->get_margin(MARGIN_LEFT),sb->get_margin(MARGIN_TOP)+vofs,w,size.y); - fit_child_in_rect(c,r); - cache_y.push_back(vofs+size.y*0.5); + fit_child_in_rect(c,r); + cache_y.push_back(vofs+size.y*0.5); - if (vofs>0) - vofs+=sep; - vofs+=size.y; + if (vofs>0) + vofs+=sep; + vofs+=size.y; - } + } - _change_notify(); - update(); - connpos_dirty=true; + _change_notify(); + update(); + connpos_dirty=true; } @@ -158,124 +158,124 @@ void GraphNode::_resort() { void GraphNode::_notification(int p_what) { - if (p_what==NOTIFICATION_DRAW) { + if (p_what==NOTIFICATION_DRAW) { - Ref sb=get_stylebox("frame"); - Ref port =get_icon("port"); - Ref close =get_icon("close"); - int close_offset = get_constant("close_offset"); - Ref title_font = get_font("title_font"); - int title_offset = get_constant("title_offset"); - Color title_color = get_color("title_color"); - Point2i icofs = -port->get_size()*0.5; - int edgeofs=get_constant("port_offset"); - icofs.y+=sb->get_margin(MARGIN_TOP); - draw_style_box(sb,Rect2(Point2(),get_size())); + Ref sb=get_stylebox(selected ? "selectedframe" : "frame"); + Ref port =get_icon("port"); + Ref close =get_icon("close"); + int close_offset = get_constant("close_offset"); + Ref title_font = get_font("title_font"); + int title_offset = get_constant("title_offset"); + Color title_color = get_color("title_color"); + Point2i icofs = -port->get_size()*0.5; + int edgeofs=get_constant("port_offset"); + icofs.y+=sb->get_margin(MARGIN_TOP); + draw_style_box(sb,Rect2(Point2(),get_size())); - int w = get_size().width-sb->get_minimum_size().x; + int w = get_size().width-sb->get_minimum_size().x; - if (show_close) - w-=close->get_width(); + if (show_close) + w-=close->get_width(); - draw_string(title_font,Point2(sb->get_margin(MARGIN_LEFT),-title_font->get_height()+title_font->get_ascent()+title_offset),title,title_color,w); - if (show_close) { - Vector2 cpos = Point2(w+sb->get_margin(MARGIN_LEFT),-close->get_height()+close_offset); - draw_texture(close,cpos); - close_rect.pos=cpos; - close_rect.size=close->get_size(); - } else { - close_rect=Rect2(); - } + draw_string(title_font,Point2(sb->get_margin(MARGIN_LEFT),-title_font->get_height()+title_font->get_ascent()+title_offset),title,title_color,w); + if (show_close) { + Vector2 cpos = Point2(w+sb->get_margin(MARGIN_LEFT),-close->get_height()+close_offset); + draw_texture(close,cpos); + close_rect.pos=cpos; + close_rect.size=close->get_size(); + } else { + close_rect=Rect2(); + } - for (Map::Element *E=slot_info.front();E;E=E->next()) { + for (Map::Element *E=slot_info.front();E;E=E->next()) { - if (E->key() < 0 || E->key()>=cache_y.size()) - continue; - if (!slot_info.has(E->key())) - continue; - const Slot &s=slot_info[E->key()]; - //left - if (s.enable_left) - port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); - if (s.enable_right) - port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); + if (E->key() < 0 || E->key()>=cache_y.size()) + continue; + if (!slot_info.has(E->key())) + continue; + const Slot &s=slot_info[E->key()]; + //left + if (s.enable_left) + port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); + if (s.enable_right) + port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); - } - } + } + } - if (p_what==NOTIFICATION_SORT_CHILDREN) { + if (p_what==NOTIFICATION_SORT_CHILDREN) { - _resort(); - } + _resort(); + } } void GraphNode::set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right) { - ERR_FAIL_COND(p_idx<0); + ERR_FAIL_COND(p_idx<0); - if (!p_enable_left && p_type_left==0 && p_color_left==Color(1,1,1,1) && !p_enable_right && p_type_right==0 && p_color_right==Color(1,1,1,1)) { - slot_info.erase(p_idx); - return; - } + if (!p_enable_left && p_type_left==0 && p_color_left==Color(1,1,1,1) && !p_enable_right && p_type_right==0 && p_color_right==Color(1,1,1,1)) { + slot_info.erase(p_idx); + return; + } - Slot s; - s.enable_left=p_enable_left; - s.type_left=p_type_left; - s.color_left=p_color_left; - s.enable_right=p_enable_right; - s.type_right=p_type_right; - s.color_right=p_color_right; - slot_info[p_idx]=s; - update(); - connpos_dirty=true; + Slot s; + s.enable_left=p_enable_left; + s.type_left=p_type_left; + s.color_left=p_color_left; + s.enable_right=p_enable_right; + s.type_right=p_type_right; + s.color_right=p_color_right; + slot_info[p_idx]=s; + update(); + connpos_dirty=true; } void GraphNode::clear_slot(int p_idx){ - slot_info.erase(p_idx); - update(); - connpos_dirty=true; + slot_info.erase(p_idx); + update(); + connpos_dirty=true; } void GraphNode::clear_all_slots(){ - slot_info.clear(); - update(); - connpos_dirty=true; + slot_info.clear(); + update(); + connpos_dirty=true; } bool GraphNode::is_slot_enabled_left(int p_idx) const{ - if (!slot_info.has(p_idx)) - return false; - return slot_info[p_idx].enable_left; + if (!slot_info.has(p_idx)) + return false; + return slot_info[p_idx].enable_left; } int GraphNode::get_slot_type_left(int p_idx) const{ - if (!slot_info.has(p_idx)) - return 0; - return slot_info[p_idx].type_left; + if (!slot_info.has(p_idx)) + return 0; + return slot_info[p_idx].type_left; } Color GraphNode::get_slot_color_left(int p_idx) const{ - if (!slot_info.has(p_idx)) - return Color(1,1,1,1); - return slot_info[p_idx].color_left; + if (!slot_info.has(p_idx)) + return Color(1,1,1,1); + return slot_info[p_idx].color_left; } bool GraphNode::is_slot_enabled_right(int p_idx) const{ - if (!slot_info.has(p_idx)) - return false; - return slot_info[p_idx].enable_right; + if (!slot_info.has(p_idx)) + return false; + return slot_info[p_idx].enable_right; } @@ -283,301 +283,305 @@ bool GraphNode::is_slot_enabled_right(int p_idx) const{ int GraphNode::get_slot_type_right(int p_idx) const{ - if (!slot_info.has(p_idx)) - return 0; - return slot_info[p_idx].type_right; + if (!slot_info.has(p_idx)) + return 0; + return slot_info[p_idx].type_right; } Color GraphNode::get_slot_color_right(int p_idx) const{ - if (!slot_info.has(p_idx)) - return Color(1,1,1,1); - return slot_info[p_idx].color_right; + if (!slot_info.has(p_idx)) + return Color(1,1,1,1); + return slot_info[p_idx].color_right; } Size2 GraphNode::get_minimum_size() const { - Ref title_font = get_font("title_font"); + Ref title_font = get_font("title_font"); - int sep=get_constant("separation"); - Ref sb=get_stylebox("frame"); - bool first=true; + int sep=get_constant("separation"); + Ref sb=get_stylebox("frame"); + bool first=true; - Size2 minsize; - minsize.x=title_font->get_string_size(title).x; - if (show_close) { - Ref close =get_icon("close"); - minsize.x+=sep+close->get_width(); - } + Size2 minsize; + minsize.x=title_font->get_string_size(title).x; + if (show_close) { + Ref close =get_icon("close"); + minsize.x+=sep+close->get_width(); + } - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Control *c=get_child(i)->cast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - minsize.y+=size.y; - minsize.x=MAX(minsize.x,size.x); + minsize.y+=size.y; + minsize.x=MAX(minsize.x,size.x); - if (first) - first=false; - else - minsize.y+=sep; - } + if (first) + first=false; + else + minsize.y+=sep; + } - return minsize+sb->get_minimum_size(); + return minsize+sb->get_minimum_size(); } void GraphNode::set_title(const String& p_title) { - title=p_title; - minimum_size_changed(); - update(); + title=p_title; + minimum_size_changed(); + update(); } String GraphNode::get_title() const{ - return title; + return title; } void GraphNode::set_offset(const Vector2& p_offset) { - offset=p_offset; - emit_signal("offset_changed"); - update(); + offset=p_offset; + emit_signal("offset_changed"); + update(); } Vector2 GraphNode::get_offset() const { - return offset; + return offset; } +void GraphNode::set_selected(bool p_selected) +{ + selected = p_selected; + update(); +} + +bool GraphNode::is_selected() +{ + return selected; +} + +void GraphNode::set_drag(bool p_drag) +{ + if (p_drag) + drag_from=get_offset(); + else + emit_signal("dragged",drag_from,get_offset()); //useful for undo/redo +} + +Vector2 GraphNode::get_drag_from() +{ + return drag_from; +} void GraphNode::set_show_close_button(bool p_enable){ - show_close=p_enable; - update(); + show_close=p_enable; + update(); } bool GraphNode::is_close_button_visible() const{ - return show_close; + return show_close; } void GraphNode::_connpos_update() { - int edgeofs=get_constant("port_offset"); - int sep=get_constant("separation"); + int edgeofs=get_constant("port_offset"); + int sep=get_constant("separation"); - Ref sb=get_stylebox("frame"); - Ref port =get_icon("port"); - conn_input_cache.clear(); - conn_output_cache.clear(); - int vofs=0; + Ref sb=get_stylebox("frame"); + conn_input_cache.clear(); + conn_output_cache.clear(); + int vofs=0; - int idx=0; + int idx=0; - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + for(int i=0;icast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - int y = sb->get_margin(MARGIN_TOP)+vofs; - int h = size.y; + int y = sb->get_margin(MARGIN_TOP)+vofs; + int h = size.y; - if (slot_info.has(idx)) { + if (slot_info.has(idx)) { - if (slot_info[idx].enable_left) { - ConnCache cc; - cc.pos=Point2i(edgeofs,y+h/2); - cc.type=slot_info[idx].type_left; - cc.color=slot_info[idx].color_left; - conn_input_cache.push_back(cc); - } - if (slot_info[idx].enable_right) { - ConnCache cc; - cc.pos=Point2i(get_size().width-edgeofs,y+h/2); - cc.type=slot_info[idx].type_right; - cc.color=slot_info[idx].color_right; - conn_output_cache.push_back(cc); - } - } + if (slot_info[idx].enable_left) { + ConnCache cc; + cc.pos=Point2i(edgeofs,y+h/2); + cc.type=slot_info[idx].type_left; + cc.color=slot_info[idx].color_left; + conn_input_cache.push_back(cc); + } + if (slot_info[idx].enable_right) { + ConnCache cc; + cc.pos=Point2i(get_size().width-edgeofs,y+h/2); + cc.type=slot_info[idx].type_right; + cc.color=slot_info[idx].color_right; + conn_output_cache.push_back(cc); + } + } - if (vofs>0) - vofs+=sep; - vofs+=size.y; - idx++; + if (vofs>0) + vofs+=sep; + vofs+=size.y; + idx++; - } + } - connpos_dirty=false; + connpos_dirty=false; } int GraphNode::get_connection_input_count() { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - return conn_input_cache.size(); + return conn_input_cache.size(); } int GraphNode::get_connection_output_count() { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - return conn_output_cache.size(); + return conn_output_cache.size(); } Vector2 GraphNode::get_connection_input_pos(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Vector2()); - return conn_input_cache[p_idx].pos; + ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Vector2()); + return conn_input_cache[p_idx].pos; } int GraphNode::get_connection_input_type(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),0); - return conn_input_cache[p_idx].type; + ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),0); + return conn_input_cache[p_idx].type; } Color GraphNode::get_connection_input_color(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Color()); - return conn_input_cache[p_idx].color; + ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Color()); + return conn_input_cache[p_idx].color; } Vector2 GraphNode::get_connection_output_pos(int p_idx){ - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Vector2()); - return conn_output_cache[p_idx].pos; + ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Vector2()); + return conn_output_cache[p_idx].pos; } int GraphNode::get_connection_output_type(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),0); - return conn_output_cache[p_idx].type; + ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),0); + return conn_output_cache[p_idx].type; } Color GraphNode::get_connection_output_color(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Color()); - return conn_output_cache[p_idx].color; + ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Color()); + return conn_output_cache[p_idx].color; } void GraphNode::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { + if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); - if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { - emit_signal("close_request"); - return; - } + Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); + if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { + emit_signal("close_request"); + return; + } + emit_signal("raise_request"); - drag_from=get_offset(); - drag_accum=Vector2(); - dragging=true; - emit_signal("raise_request"); - - } - - if (p_ev.type==InputEvent::MOUSE_BUTTON && !p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - - dragging=false; - emit_signal("dragged",drag_from,get_offset()); //useful for undo/redo - } - - if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { - - drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); - set_offset(drag_from+drag_accum); - } + } } void GraphNode::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_title","title"),&GraphNode::set_title); - ObjectTypeDB::bind_method(_MD("get_title"),&GraphNode::get_title); - ObjectTypeDB::bind_method(_MD("_input_event"),&GraphNode::_input_event); + ObjectTypeDB::bind_method(_MD("set_title","title"),&GraphNode::set_title); + ObjectTypeDB::bind_method(_MD("get_title"),&GraphNode::get_title); + ObjectTypeDB::bind_method(_MD("_input_event"),&GraphNode::_input_event); - ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right"),&GraphNode::set_slot); - ObjectTypeDB::bind_method(_MD("clear_slot","idx"),&GraphNode::clear_slot); - ObjectTypeDB::bind_method(_MD("clear_all_slots","idx"),&GraphNode::clear_all_slots); - ObjectTypeDB::bind_method(_MD("is_slot_enabled_left","idx"),&GraphNode::is_slot_enabled_left); - ObjectTypeDB::bind_method(_MD("get_slot_type_left","idx"),&GraphNode::get_slot_type_left); - ObjectTypeDB::bind_method(_MD("get_slot_color_left","idx"),&GraphNode::get_slot_color_left); - ObjectTypeDB::bind_method(_MD("is_slot_enabled_right","idx"),&GraphNode::is_slot_enabled_right); - ObjectTypeDB::bind_method(_MD("get_slot_type_right","idx"),&GraphNode::get_slot_type_right); - ObjectTypeDB::bind_method(_MD("get_slot_color_right","idx"),&GraphNode::get_slot_color_right); + ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right"),&GraphNode::set_slot); + ObjectTypeDB::bind_method(_MD("clear_slot","idx"),&GraphNode::clear_slot); + ObjectTypeDB::bind_method(_MD("clear_all_slots","idx"),&GraphNode::clear_all_slots); + ObjectTypeDB::bind_method(_MD("is_slot_enabled_left","idx"),&GraphNode::is_slot_enabled_left); + ObjectTypeDB::bind_method(_MD("get_slot_type_left","idx"),&GraphNode::get_slot_type_left); + ObjectTypeDB::bind_method(_MD("get_slot_color_left","idx"),&GraphNode::get_slot_color_left); + ObjectTypeDB::bind_method(_MD("is_slot_enabled_right","idx"),&GraphNode::is_slot_enabled_right); + ObjectTypeDB::bind_method(_MD("get_slot_type_right","idx"),&GraphNode::get_slot_type_right); + ObjectTypeDB::bind_method(_MD("get_slot_color_right","idx"),&GraphNode::get_slot_color_right); - ObjectTypeDB::bind_method(_MD("set_offset","offset"),&GraphNode::set_offset); - ObjectTypeDB::bind_method(_MD("get_offset"),&GraphNode::get_offset); + ObjectTypeDB::bind_method(_MD("set_offset","offset"),&GraphNode::set_offset); + ObjectTypeDB::bind_method(_MD("get_offset"),&GraphNode::get_offset); - ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count); - ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count); + ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count); + ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count); - ObjectTypeDB::bind_method(_MD("get_connection_output_pos","idx"),&GraphNode::get_connection_output_pos); - ObjectTypeDB::bind_method(_MD("get_connection_output_type","idx"),&GraphNode::get_connection_output_type); - ObjectTypeDB::bind_method(_MD("get_connection_output_color","idx"),&GraphNode::get_connection_output_color); - ObjectTypeDB::bind_method(_MD("get_connection_input_pos","idx"),&GraphNode::get_connection_input_pos); - ObjectTypeDB::bind_method(_MD("get_connection_input_type","idx"),&GraphNode::get_connection_input_type); - ObjectTypeDB::bind_method(_MD("get_connection_input_color","idx"),&GraphNode::get_connection_input_color); + ObjectTypeDB::bind_method(_MD("get_connection_output_pos","idx"),&GraphNode::get_connection_output_pos); + ObjectTypeDB::bind_method(_MD("get_connection_output_type","idx"),&GraphNode::get_connection_output_type); + ObjectTypeDB::bind_method(_MD("get_connection_output_color","idx"),&GraphNode::get_connection_output_color); + ObjectTypeDB::bind_method(_MD("get_connection_input_pos","idx"),&GraphNode::get_connection_input_pos); + ObjectTypeDB::bind_method(_MD("get_connection_input_type","idx"),&GraphNode::get_connection_input_type); + ObjectTypeDB::bind_method(_MD("get_connection_input_color","idx"),&GraphNode::get_connection_input_color); - ObjectTypeDB::bind_method(_MD("set_show_close_button","show"),&GraphNode::set_show_close_button); - ObjectTypeDB::bind_method(_MD("is_close_button_visible"),&GraphNode::is_close_button_visible); + ObjectTypeDB::bind_method(_MD("set_show_close_button","show"),&GraphNode::set_show_close_button); + ObjectTypeDB::bind_method(_MD("is_close_button_visible"),&GraphNode::is_close_button_visible); - ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"show_close"),_SCS("set_show_close_button"),_SCS("is_close_button_visible")); + ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"show_close"),_SCS("set_show_close_button"),_SCS("is_close_button_visible")); - ADD_SIGNAL(MethodInfo("offset_changed")); - ADD_SIGNAL(MethodInfo("dragged",PropertyInfo(Variant::VECTOR2,"from"),PropertyInfo(Variant::VECTOR2,"to"))); - ADD_SIGNAL(MethodInfo("raise_request")); - ADD_SIGNAL(MethodInfo("close_request")); + ADD_SIGNAL(MethodInfo("offset_changed")); + ADD_SIGNAL(MethodInfo("dragged",PropertyInfo(Variant::VECTOR2,"from"),PropertyInfo(Variant::VECTOR2,"to"))); + ADD_SIGNAL(MethodInfo("raise_request")); + ADD_SIGNAL(MethodInfo("close_request")); } GraphNode::GraphNode() { - - dragging=false; - show_close=false; - connpos_dirty=true; + show_close=false; + connpos_dirty=true; } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 0d5cbf8dd3..6bece22ac5 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -5,96 +5,101 @@ class GraphNode : public Container { - OBJ_TYPE(GraphNode,Container); + OBJ_TYPE(GraphNode,Container); - struct Slot { - bool enable_left; - int type_left; - Color color_left; - bool enable_right; - int type_right; - Color color_right; + struct Slot { + bool enable_left; + int type_left; + Color color_left; + bool enable_right; + int type_right; + Color color_right; - Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); }; - }; + Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); } + }; - String title; - bool show_close; - Vector2 offset; + String title; + bool show_close; + Vector2 offset; - Rect2 close_rect; + Rect2 close_rect; - Vector cache_y; + Vector cache_y; - struct ConnCache { - Vector2 pos; - int type; - Color color; - }; + struct ConnCache { + Vector2 pos; + int type; + Color color; + }; - Vector conn_input_cache; - Vector conn_output_cache; + Vector conn_input_cache; + Vector conn_output_cache; - Map slot_info; + Map slot_info; - bool connpos_dirty; + bool connpos_dirty; - void _connpos_update(); - void _resort(); + void _connpos_update(); + void _resort(); - Vector2 drag_from; - Vector2 drag_accum; - bool dragging; + Vector2 drag_from; + bool selected; protected: - void _input_event(const InputEvent& p_ev); - void _notification(int p_what); - static void _bind_methods(); + void _input_event(const InputEvent& p_ev); + void _notification(int p_what); + static void _bind_methods(); - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List *p_list) const; + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List *p_list) const; public: - void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right); - void clear_slot(int p_idx); - void clear_all_slots(); - bool is_slot_enabled_left(int p_idx) const; - int get_slot_type_left(int p_idx) const; - Color get_slot_color_left(int p_idx) const; - bool is_slot_enabled_right(int p_idx) const; - int get_slot_type_right(int p_idx) const; - Color get_slot_color_right(int p_idx) const; + void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right); + void clear_slot(int p_idx); + void clear_all_slots(); + bool is_slot_enabled_left(int p_idx) const; + int get_slot_type_left(int p_idx) const; + Color get_slot_color_left(int p_idx) const; + bool is_slot_enabled_right(int p_idx) const; + int get_slot_type_right(int p_idx) const; + Color get_slot_color_right(int p_idx) const; - void set_title(const String& p_title); - String get_title() const; + void set_title(const String& p_title); + String get_title() const; - void set_offset(const Vector2& p_offset); - Vector2 get_offset() const; + void set_offset(const Vector2& p_offset); + Vector2 get_offset() const; - void set_show_close_button(bool p_enable); - bool is_close_button_visible() const; + void set_selected(bool p_selected); + bool is_selected(); - int get_connection_input_count() ; - int get_connection_output_count() ; - Vector2 get_connection_input_pos(int p_idx); - int get_connection_input_type(int p_idx); - Color get_connection_input_color(int p_idx); - Vector2 get_connection_output_pos(int p_idx); - int get_connection_output_type(int p_idx); - Color get_connection_output_color(int p_idx); + void set_drag(bool p_drag); + Vector2 get_drag_from(); + void set_show_close_button(bool p_enable); + bool is_close_button_visible() const; - virtual Size2 get_minimum_size() const; + int get_connection_input_count() ; + int get_connection_output_count() ; + Vector2 get_connection_input_pos(int p_idx); + int get_connection_input_type(int p_idx); + Color get_connection_input_color(int p_idx); + Vector2 get_connection_output_pos(int p_idx); + int get_connection_output_type(int p_idx); + Color get_connection_output_color(int p_idx); - GraphNode(); + + virtual Size2 get_minimum_size() const; + + GraphNode(); }; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 9a9048e3e5..667dfd4632 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -558,9 +558,11 @@ void make_default_theme() { // GraphNode Ref graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5); + Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5); //graphsb->set_expand_margin_size(MARGIN_LEFT,10); //graphsb->set_expand_margin_size(MARGIN_RIGHT,10); t->set_stylebox("frame","GraphNode", graphsb ); + t->set_stylebox("selectedframe","GraphNode", graphsbselected ); t->set_constant("separation","GraphNode", 1 ); t->set_icon("port","GraphNode", make_icon( graph_port_png ) ); t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) ); diff --git a/scene/resources/default_theme/graph_node_selected.png b/scene/resources/default_theme/graph_node_selected.png new file mode 100644 index 0000000000..06a9db4409 Binary files /dev/null and b/scene/resources/default_theme/graph_node_selected.png differ diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 03d851e749..a00651a0b3 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -114,6 +114,11 @@ static const unsigned char graph_node_close_png[]={ }; +static const unsigned char graph_node_selected_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x40,0x8,0x6,0x0,0x0,0x0,0x13,0x7d,0xf7,0x96,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x7,0x12,0x1,0xc,0x6,0x23,0x98,0xc7,0x50,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x2,0x46,0x49,0x44,0x41,0x54,0x58,0xc3,0xed,0x97,0xcd,0x6a,0x13,0x51,0x14,0xc7,0x7f,0xe7,0xce,0x34,0x49,0xd,0xa6,0xb1,0x2a,0xe2,0x7,0x74,0xa1,0x6e,0x4,0x85,0xe2,0x3,0xb8,0x72,0x21,0xba,0x16,0x5c,0xb9,0x16,0x4,0x7d,0x84,0x3e,0x82,0x82,0xe0,0xda,0x95,0x2f,0x60,0x71,0xe1,0xca,0x7,0xd0,0x82,0xa5,0x6e,0xd4,0x45,0xc1,0x8f,0x4a,0x6c,0x9a,0x46,0x62,0x66,0xa6,0x73,0xef,0x71,0xe1,0x4c,0x92,0x99,0x4c,0x93,0x36,0xdd,0xc9,0xfc,0x37,0x77,0x3e,0xee,0xfd,0xdd,0x73,0xfe,0xf7,0xc,0xcc,0x11,0x86,0x12,0xc0,0x0,0x5e,0x32,0xa,0x59,0x29,0xe0,0x0,0x9b,0x8c,0xca,0xc8,0x24,0x3,0x1c,0x3,0x16,0x81,0xd3,0x40,0x3,0x98,0xcb,0x1,0xf6,0x80,0x2e,0xd0,0x2,0xda,0xc0,0x1f,0xc0,0xa5,0xbb,0xd6,0x81,0x4b,0xb,0xc7,0x9b,0xf,0x6a,0xd5,0xda,0xad,0x4a,0xa5,0x7a,0x81,0x2,0x45,0x51,0xf8,0x35,0x8,0x83,0xd7,0xbb,0xbf,0x3b,0xcf,0x81,0xcf,0x40,0x4f,0x92,0x9d,0x96,0x16,0x9b,0x27,0x9f,0x5c,0x5c,0xba,0x7c,0xfb,0xfe,0xcb,0x3b,0x34,0x2b,0x27,0x8a,0xd6,0xd3,0x89,0x76,0x78,0x71,0xef,0x15,0x5f,0x36,0x3f,0xad,0xb6,0x3b,0xdb,0x8f,0x81,0x4d,0x1,0x6a,0xc0,0xf2,0xd9,0x33,0xe7,0xdf,0xac,0xbc,0x7d,0x54,0xdf,0x73,0x11,0x81,0xed,0x17,0x2,0x6a,0xde,0x3c,0x73,0xa6,0xc2,0xca,0x8d,0xa7,0xbd,0x1f,0x3f,0xbf,0xdd,0x4,0xd6,0xfc,0xc4,0x87,0xba,0xef,0xf9,0xf5,0x6e,0xb4,0xc3,0x24,0xf5,0xe3,0x1e,0x7d,0x7a,0xf8,0x9e,0x5f,0x4f,0xd2,0x96,0x14,0xe0,0x1,0x58,0xb5,0x39,0xdb,0x1d,0x82,0x19,0x5c,0xe7,0xe4,0xa5,0x0,0x4d,0x8f,0x44,0x71,0xa8,0x2a,0x22,0x92,0x81,0x4c,0x92,0x3f,0x7a,0xe3,0xd4,0xe2,0x54,0x41,0xc1,0x13,0xf,0xc5,0xe1,0x54,0x31,0x22,0x8,0xa6,0x10,0x96,0x1,0x58,0x1d,0x4e,0x88,0x35,0x1e,0x79,0x9e,0xd6,0xd0,0x94,0x8,0x54,0xb3,0x93,0x1c,0x8a,0x41,0x6,0x63,0xfa,0x6c,0x5f,0x40,0xe4,0xa2,0xcc,0x4b,0x23,0x32,0xd8,0x37,0x4e,0x52,0x99,0x1c,0x41,0x2e,0x4c,0x9b,0xdd,0x6c,0xec,0xbe,0x20,0x5,0xe5,0xb0,0xca,0x99,0x68,0x93,0x48,0x14,0x41,0x30,0x22,0x3,0x63,0x5,0x41,0x51,0x3c,0x31,0x93,0x8f,0x31,0xf3,0xed,0x6a,0xf6,0x5b,0xfe,0xe7,0x85,0x9b,0x0,0x98,0x52,0x34,0x7,0x2a,0xa4,0xb4,0x74,0x8b,0x4c,0x2d,0x2a,0xa6,0xb1,0x42,0x32,0x8c,0x1b,0x39,0x3c,0x7b,0x37,0xbd,0x90,0xec,0x51,0x52,0x88,0x5d,0x3c,0x36,0x21,0xd,0x39,0x4d,0x4d,0x72,0xc5,0x94,0x1,0xac,0xde,0x7d,0x3f,0xbb,0x89,0xf1,0x9e,0x65,0xf9,0xea,0xf5,0x3,0x2d,0x5a,0x5b,0x7f,0x57,0x1c,0xc1,0x6e,0xb7,0x73,0xe8,0x8,0xc,0x47,0x54,0x9,0x28,0x1,0x25,0xa0,0x4,0x94,0x80,0x12,0x50,0x2,0xfe,0x4b,0x80,0x14,0xf4,0x88,0x87,0x8e,0xc0,0xcd,0xb0,0xd6,0xa5,0x0,0x7,0x4,0xd6,0xda,0xb0,0xe0,0x27,0x6d,0x7c,0x55,0xc,0xd6,0xda,0x10,0x8,0x0,0x67,0x92,0x56,0x76,0x3b,0x8,0xfb,0x1b,0xad,0xf6,0x16,0x93,0x20,0x2e,0x86,0x56,0x7b,0x8b,0x20,0xec,0x6f,0x0,0xdb,0x80,0x4d,0x3b,0xd7,0x5,0xe0,0x5a,0xa3,0xde,0x7c,0x56,0xab,0xce,0x5f,0xf1,0x3c,0xaf,0xd0,0x5c,0x6b,0xad,0xb,0xc2,0xfe,0xc7,0x6e,0xaf,0xf3,0x10,0xf8,0x0,0xec,0xca,0x48,0xb,0xd7,0x0,0xce,0x1,0xa7,0x80,0xea,0x3e,0xcd,0x77,0x8,0xfc,0x2,0xbe,0x27,0x7d,0xb4,0x95,0x9c,0xa1,0x7e,0xda,0xf,0xee,0x93,0x85,0x26,0x29,0xc7,0x33,0x1a,0x3f,0xae,0xbf,0xf0,0x27,0xf6,0x42,0xf6,0xf5,0xfd,0xae,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + static const unsigned char graph_port_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0xa,0x0,0x0,0x0,0xa,0x8,0x6,0x0,0x0,0x0,0x8d,0x32,0xcf,0xbd,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x0,0x0,0x0,0x0,0x0,0xf9,0x43,0xbb,0x7f,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0xc,0x14,0x17,0x20,0x3,0xeb,0x8f,0x3a,0xdb,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x1,0x65,0x49,0x44,0x41,0x54,0x18,0xd3,0x4d,0xd0,0x4f,0x6b,0xda,0x70,0x1c,0x7,0xe0,0xcf,0x37,0x7f,0x7e,0x49,0x66,0xd2,0x64,0x61,0x5,0x61,0x76,0x47,0xf1,0xa4,0x2d,0xdb,0x75,0x5,0x11,0x84,0xb0,0x5e,0xeb,0xd9,0xeb,0xf4,0x6d,0xec,0x2d,0xf8,0x26,0xb6,0x77,0xe0,0x45,0xba,0xa3,0x6c,0xa0,0x3b,0xad,0x39,0xb6,0x36,0x8,0x1b,0x4b,0x32,0xd2,0xc6,0x6c,0x9a,0x4f,0x4f,0x85,0x3e,0x2f,0xe1,0x11,0x0,0x20,0x29,0xd3,0xe9,0xd4,0xda,0x6e,0xb7,0x23,0xdf,0xf7,0xbb,0x0,0x90,0xe7,0xf9,0x8f,0x66,0xb3,0xf9,0x79,0x36,0x9b,0x55,0x22,0x42,0x83,0xa4,0x44,0x51,0xf4,0xea,0xe2,0xe2,0xc3,0xf7,0xf1,0x78,0xdc,0xa,0x82,0x40,0x8,0x20,0xcf,0x32,0x2e,0x97,0xcb,0x4f,0x51,0x14,0xbd,0x25,0xf9,0x5b,0x26,0x93,0x89,0xdd,0xe9,0x74,0xe2,0xf7,0xe7,0xe7,0x27,0x59,0xfa,0x87,0x65,0xb9,0x13,0x0,0xb0,0x1d,0x9b,0xe1,0xcb,0x50,0xbe,0x5e,0x5d,0xdd,0xfe,0xbc,0xbe,0x6e,0x6b,0x49,0x92,0x8c,0x4e,0x7b,0xa7,0xad,0xbf,0x79,0x4e,0xd3,0x54,0x12,0x86,0x21,0xc2,0x30,0x84,0x32,0x95,0xe4,0x79,0xc6,0xde,0xd9,0x59,0x2b,0x49,0xee,0x46,0x86,0xeb,0xba,0x5d,0xfb,0x85,0x23,0x87,0xfd,0x1e,0xb6,0xed,0x40,0xd7,0x35,0x0,0x40,0x7d,0x38,0xa0,0xdc,0xed,0x44,0x37,0x74,0xb8,0xae,0xd7,0x35,0x48,0x62,0xff,0xff,0x1f,0xfc,0x20,0x80,0xae,0xe9,0x78,0x42,0x0,0xca,0xb2,0x90,0x65,0x19,0x58,0xd7,0xd0,0x8a,0xa2,0x58,0xa7,0x69,0x56,0x6b,0xa2,0x51,0x29,0x5,0xcb,0x52,0xb0,0x94,0x5,0x4b,0x29,0x88,0x8,0xd3,0x34,0xad,0x8b,0xfb,0x62,0xad,0xf,0x6,0x83,0xb8,0xaa,0xaa,0xb1,0xe7,0x79,0xbe,0x77,0x74,0x44,0xb7,0xe1,0x89,0x69,0x1a,0x28,0xcb,0x92,0x9b,0xcd,0x46,0x56,0xab,0xd5,0x86,0xe4,0x47,0x21,0x29,0xc3,0xe1,0xf0,0xb8,0xdf,0xef,0x7f,0x6b,0xb7,0xdb,0xaf,0x1b,0x8d,0x86,0x46,0x10,0xf,0xf7,0xf,0x75,0x1c,0xc7,0x77,0x8b,0xc5,0xe2,0xdd,0x7c,0x3e,0xff,0x25,0xcf,0xc3,0x6f,0x6e,0x6f,0x2e,0x1d,0xdb,0xe9,0x9,0x80,0xb2,0x2a,0xd7,0x27,0xad,0x37,0x5f,0x9e,0xc2,0x1f,0x1,0x3a,0xe6,0xa5,0x7b,0xef,0xf2,0xf3,0xcd,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index b4fb14dbbc..a0f7edbd93 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -37,596 +37,596 @@ void GraphColorRampEdit::_input_event(const InputEvent& p_event) { - if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { - - points.remove(grabbed); - grabbed=-1; - update(); - emit_signal("ramp_changed"); - accept_event(); - } - - if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { + + points.remove(grabbed); + grabbed=-1; + update(); + emit_signal("ramp_changed"); + accept_event(); + } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { - update(); - int x = p_event.mouse_button.x; - int total_w = get_size().width-get_size().height-3; - if (x>total_w+3) { - - if (grabbed==-1) - return; - Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10); - picker->set_color(points[grabbed].color); - popup->set_pos(get_global_pos()-Size2(0,ms.height)); - popup->set_size(ms); - popup->popup(); - return; - } - - - float ofs = CLAMP(x/float(total_w),0,1); - - grabbed=-1; - grabbing=true; - int pos=-1; - for(int i=0;itotal_w+3) { + + if (grabbed==-1) + return; + Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10); + picker->set_color(points[grabbed].color); + popup->set_pos(get_global_pos()-Size2(0,ms.height)); + popup->set_size(ms); + popup->popup(); + return; + } + + + float ofs = CLAMP(x/float(total_w),0,1); + + grabbed=-1; + grabbing=true; + int pos=-1; + for(int i=0;iconnect("color_changed",this,"_color_changed"); - } - if (p_what==NOTIFICATION_DRAW) { + if (p_what==NOTIFICATION_ENTER_TREE) { + picker->connect("color_changed",this,"_color_changed"); + } + if (p_what==NOTIFICATION_DRAW) { - Point prev; - prev.offset=0; - prev.color=Color(0,0,0); - int w = get_size().x; - int h = get_size().y; + Point prev; + prev.offset=0; + prev.color=Color(0,0,0); + int w = get_size().x; + int h = get_size().y; - int total_w = get_size().width-get_size().height-3; + int total_w = get_size().width-get_size().height-3; - for(int i=-1;i points; - Vector colors; - points.push_back(Vector2(prev.offset*total_w,h)); - points.push_back(Vector2(prev.offset*total_w,0)); - points.push_back(Vector2(next.offset*total_w,0)); - points.push_back(Vector2(next.offset*total_w,h)); - colors.push_back(prev.color); - colors.push_back(prev.color); - colors.push_back(next.color); - colors.push_back(next.color); - draw_primitive(points,colors,Vector()); - prev=next; - } + Vector points; + Vector colors; + points.push_back(Vector2(prev.offset*total_w,h)); + points.push_back(Vector2(prev.offset*total_w,0)); + points.push_back(Vector2(next.offset*total_w,0)); + points.push_back(Vector2(next.offset*total_w,h)); + colors.push_back(prev.color); + colors.push_back(prev.color); + colors.push_back(next.color); + colors.push_back(next.color); + draw_primitive(points,colors,Vector()); + prev=next; + } - for(int i=0;i& p_offsets,const Vector& p_colors) { - ERR_FAIL_COND(p_offsets.size()!=p_colors.size()); - points.clear(); - for(int i=0;i GraphColorRampEdit::get_offsets() const{ - Vector ret; - for(int i=0;i ret; + for(int i=0;i GraphColorRampEdit::get_colors() const{ - Vector ret; - for(int i=0;i ret; + for(int i=0;iadd_child(picker); - popup->set_child_rect(picker); - add_child(popup); + popup = memnew( PopupPanel ); + picker = memnew( ColorPicker ); + popup->add_child(picker); + popup->set_child_rect(picker); + add_child(popup); } //////////// void GraphCurveMapEdit::_input_event(const InputEvent& p_event) { - if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { + if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { - points.remove(grabbed); - grabbed=-1; - update(); - emit_signal("curve_changed"); - accept_event(); - } + points.remove(grabbed); + grabbed=-1; + update(); + emit_signal("curve_changed"); + accept_event(); + } - if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { - update(); - Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size(); - p.y=1.0-p.y; - grabbed=-1; - grabbing=true; + update(); + Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size(); + p.y=1.0-p.y; + grabbed=-1; + grabbing=true; - for(int i=0;icurve[cd->outline][lastx] = lasty; - } - else - { - cd->curve_ptr[cd->outline][lastx] = lasty; - if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax); - } + { + cd->curve[cd->outline][lastx] = lasty; + } + else + { + cd->curve_ptr[cd->outline][lastx] = lasty; + if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax); + } */ - /* loop over the curve */ - for (i = 0; i < ntimes; i++) - { - /* increment the x values */ - x += dx; - dx += dx2; - dx2 += dx3; - - /* increment the y values */ - y += dy; - dy += dy2; - dy2 += dy3; - - newx = CLAMP ((Math::round (x)), 0, xmax); - newy = CLAMP ((Math::round (y)), 0, ymax); - - /* if this point is different than the last one...then draw it */ - if ((lastx != newx) || (lasty != newy)) - { + /* loop over the curve */ + for (i = 0; i < ntimes; i++) + { + /* increment the x values */ + x += dx; + dx += dx2; + dx2 += dx3; + + /* increment the y values */ + y += dy; + dy += dy2; + dy2 += dy3; + + newx = CLAMP ((Math::round (x)), 0, xmax); + newy = CLAMP ((Math::round (y)), 0, ymax); + + /* if this point is different than the last one...then draw it */ + if ((lastx != newx) || (lasty != newy)) + { #if 0 - if(fix255) - { - /* use fixed array size (for the curve graph) */ - cd->curve[cd->outline][newx] = newy; - } - else - { - /* use dynamic allocated curve_ptr (for the real curve) */ - cd->curve_ptr[cd->outline][newx] = newy; - - if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy); - } + if(fix255) + { + /* use fixed array size (for the curve graph) */ + cd->curve[cd->outline][newx] = newy; + } + else + { + /* use dynamic allocated curve_ptr (for the real curve) */ + cd->curve_ptr[cd->outline][newx] = newy; + + if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy); + } #endif - draw_line(Vector2(lastx,ymax-lasty),Vector2(newx,ymax-newy),Color(0.8,0.8,0.8,0.8),2.0); - } + draw_line(Vector2(lastx,ymax-lasty),Vector2(newx,ymax-newy),Color(0.8,0.8,0.8,0.8),2.0); + } - lastx = newx; - lasty = newy; - } + lastx = newx; + lasty = newy; + } } void GraphCurveMapEdit::_notification(int p_what){ - if (p_what==NOTIFICATION_DRAW) { + if (p_what==NOTIFICATION_DRAW) { - draw_style_box(get_stylebox("bg","Tree"),Rect2(Point2(),get_size())); + draw_style_box(get_stylebox("bg","Tree"),Rect2(Point2(),get_size())); - int w = get_size().x; - int h = get_size().y; + int w = get_size().x; + int h = get_size().y; - Vector2 prev=Vector2(0,0); - Vector2 prev2=Vector2(0,0); + Vector2 prev=Vector2(0,0); + Vector2 prev2=Vector2(0,0); - for(int i=-1;i=points.size()) { - next=Vector2(1,1); - } else { - next=Vector2(points[i+1].offset,points[i+1].height); - } + Vector2 next; + Vector2 next2; + if (i+1>=points.size()) { + next=Vector2(1,1); + } else { + next=Vector2(points[i+1].offset,points[i+1].height); + } - if (i+2>=points.size()) { - next2=Vector2(1,1); - } else { - next2=Vector2(points[i+2].offset,points[i+2].height); - } + if (i+2>=points.size()) { + next2=Vector2(1,1); + } else { + next2=Vector2(points[i+2].offset,points[i+2].height); + } - /*if (i==-1 && prev.offset==next.offset) { - prev=next; - continue; - }*/ + /*if (i==-1 && prev.offset==next.offset) { + prev=next; + continue; + }*/ - _plot_curve(prev2,prev,next,next2); + _plot_curve(prev2,prev,next,next2); - prev2=prev; - prev=next; - } + prev2=prev; + prev=next; + } - for(int i=0;i& p_points) { - points.clear(); - for(int i=0;i GraphCurveMapEdit::get_points() const { - Vector ret; - for(int i=0;i ret; + for(int i=0;iget_undo_redo(); - ur->create_action("Change Scalar Constant",true); - ur->add_do_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,p_value); - ur->add_undo_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,graph->scalar_const_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Constant",true); + ur->add_do_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,p_value); + ur->add_undo_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,graph->scalar_const_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_const_changed(double p_value, int p_id,Array p_arr){ - Vector3 val; - for(int i=0;iget_undo_redo(); - ur->create_action("Change Vec Constant",true); - ur->add_do_method(graph.ptr(),"vec_const_node_set_value",type,p_id,val); - ur->add_undo_method(graph.ptr(),"vec_const_node_set_value",type,p_id,graph->vec_const_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Constant",true); + ur->add_do_method(graph.ptr(),"vec_const_node_set_value",type,p_id,val); + ur->add_undo_method(graph.ptr(),"vec_const_node_set_value",type,p_id,graph->vec_const_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_rgb_const_changed(const Color& p_color, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change RGB Constant",true); - ur->add_do_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,p_color); - ur->add_undo_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,graph->rgb_const_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change RGB Constant",true); + ur->add_do_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,p_color); + ur->add_undo_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,graph->rgb_const_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_scalar_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Scalar Operator"); - ur->add_do_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,graph->scalar_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Operator"); + ur->add_do_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,graph->scalar_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Vec Operator"); - ur->add_do_method(graph.ptr(),"vec_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"vec_op_node_set_op",type,p_id,graph->vec_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Operator"); + ur->add_do_method(graph.ptr(),"vec_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"vec_op_node_set_op",type,p_id,graph->vec_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_scalar_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change VecxScalar Operator"); - ur->add_do_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,graph->vec_scalar_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change VecxScalar Operator"); + ur->add_do_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,graph->vec_scalar_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_rgb_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change RGB Operator"); - ur->add_do_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,graph->rgb_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change RGB Operator"); + ur->add_do_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,graph->rgb_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_xform_inv_rev_changed(bool p_enabled, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Toggle Rot Only"); - ur->add_do_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,p_enabled); - ur->add_undo_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,graph->xform_vec_mult_node_get_no_translation(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Toggle Rot Only"); + ur->add_do_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,p_enabled); + ur->add_undo_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,graph->xform_vec_mult_node_get_no_translation(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_scalar_func_changed(int p_func, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Scalar Function"); - ur->add_do_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,p_func); - ur->add_undo_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,graph->scalar_func_node_get_function(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Function"); + ur->add_do_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,p_func); + ur->add_undo_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,graph->scalar_func_node_get_function(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_func_changed(int p_func, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Vec Function"); - ur->add_do_method(graph.ptr(),"vec_func_node_set_function",type,p_id,p_func); - ur->add_undo_method(graph.ptr(),"vec_func_node_set_function",type,p_id,graph->vec_func_node_get_function(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Function"); + ur->add_do_method(graph.ptr(),"vec_func_node_set_function",type,p_id,p_func); + ur->add_undo_method(graph.ptr(),"vec_func_node_set_function",type,p_id,graph->vec_func_node_get_function(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_scalar_input_changed(double p_value,int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Scalar Uniform",true); - ur->add_do_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,p_value); - ur->add_undo_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,graph->scalar_input_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Uniform",true); + ur->add_do_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,p_value); + ur->add_undo_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,graph->scalar_input_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_input_changed(double p_value, int p_id,Array p_arr){ - Vector3 val; - for(int i=0;iget_undo_redo(); - ur->create_action("Change Vec Uniform",true); - ur->add_do_method(graph.ptr(),"vec_input_node_set_value",type,p_id,val); - ur->add_undo_method(graph.ptr(),"vec_input_node_set_value",type,p_id,graph->vec_input_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Uniform",true); + ur->add_do_method(graph.ptr(),"vec_input_node_set_value",type,p_id,val); + ur->add_undo_method(graph.ptr(),"vec_input_node_set_value",type,p_id,graph->vec_input_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){ - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); - ped_popup->popup(); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); + ped_popup->popup(); } void ShaderGraphView::_xform_const_changed(int p_id, Node *p_button){ - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); - ped_popup->popup(); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); + ped_popup->popup(); } void ShaderGraphView::_rgb_input_changed(const Color& p_color, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change RGB Uniform",true); - ur->add_do_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,p_color); - ur->add_undo_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,graph->rgb_input_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change RGB Uniform",true); + ur->add_do_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,p_color); + ur->add_undo_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,graph->rgb_input_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_tex_input_change(int p_id, Node *p_button){ @@ -879,180 +879,180 @@ void ShaderGraphView::_cube_input_change(int p_id){ void ShaderGraphView::_variant_edited() { - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change XForm Uniform"); - ur->add_do_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,graph->xform_const_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change XForm Uniform"); + ur->add_do_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,graph->xform_const_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_INPUT) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_INPUT) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change XForm Uniform"); - ur->add_do_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,graph->xform_input_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change XForm Uniform"); + ur->add_do_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,graph->xform_input_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_TEXTURE_INPUT) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_TEXTURE_INPUT) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Texture Uniform"); - ur->add_do_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,graph->texture_input_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Texture Uniform"); + ur->add_do_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,graph->texture_input_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_CUBEMAP_INPUT) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_CUBEMAP_INPUT) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Cubemap Uniform"); - ur->add_do_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,graph->cubemap_input_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Cubemap Uniform"); + ur->add_do_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,graph->cubemap_input_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } } void ShaderGraphView::_comment_edited(int p_id,Node* p_button) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - TextEdit *te=p_button->cast_to(); - ur->create_action("Change Comment",true); - ur->add_do_method(graph.ptr(),"comment_node_set_text",type,p_id,te->get_text()); - ur->add_undo_method(graph.ptr(),"comment_node_set_text",type,p_id,graph->comment_node_get_text(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + TextEdit *te=p_button->cast_to(); + ur->create_action("Change Comment",true); + ur->add_do_method(graph.ptr(),"comment_node_set_text",type,p_id,te->get_text()); + ur->add_undo_method(graph.ptr(),"comment_node_set_text",type,p_id,graph->comment_node_get_text(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_color_ramp_changed(int p_id,Node* p_ramp) { - GraphColorRampEdit *cr=p_ramp->cast_to(); + GraphColorRampEdit *cr=p_ramp->cast_to(); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - Vector offsets=cr->get_offsets(); - Vector colors=cr->get_colors(); + Vector offsets=cr->get_offsets(); + Vector colors=cr->get_colors(); - DVector new_offsets; - DVector new_colors; - { - new_offsets.resize(offsets.size()); - new_colors.resize(colors.size()); - DVector::Write ow=new_offsets.write(); - DVector::Write cw=new_colors.write(); - for(int i=0;i new_offsets; + DVector new_colors; + { + new_offsets.resize(offsets.size()); + new_colors.resize(colors.size()); + DVector::Write ow=new_offsets.write(); + DVector::Write cw=new_colors.write(); + for(int i=0;i old_offsets=graph->color_ramp_node_get_offsets(type,p_id); - DVector old_colors=graph->color_ramp_node_get_colors(type,p_id); + DVector old_offsets=graph->color_ramp_node_get_offsets(type,p_id); + DVector old_colors=graph->color_ramp_node_get_colors(type,p_id); - if (old_offsets.size()!=new_offsets.size()) - ur->create_action("Add/Remove to Color Ramp"); - else - ur->create_action("Modify Color Ramp",true); + if (old_offsets.size()!=new_offsets.size()) + ur->create_action("Add/Remove to Color Ramp"); + else + ur->create_action("Modify Color Ramp",true); - ur->add_do_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,new_colors,new_offsets); - ur->add_undo_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,old_colors,old_offsets); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + ur->add_do_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,new_colors,new_offsets); + ur->add_undo_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,old_colors,old_offsets); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_curve_changed(int p_id,Node* p_curve) { - GraphCurveMapEdit *cr=p_curve->cast_to(); + GraphCurveMapEdit *cr=p_curve->cast_to(); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - Vector points=cr->get_points(); + Vector points=cr->get_points(); - DVector new_points; - { - new_points.resize(points.size()); - DVector::Write ow=new_points.write(); - for(int i=0;i new_points; + { + new_points.resize(points.size()); + DVector::Write ow=new_points.write(); + for(int i=0;i old_points=graph->curve_map_node_get_points(type,p_id); + DVector old_points=graph->curve_map_node_get_points(type,p_id); - if (old_points.size()!=new_points.size()) - ur->create_action("Add/Remove to Curve Map"); - else - ur->create_action("Modify Curve Map",true); + if (old_points.size()!=new_points.size()) + ur->create_action("Add/Remove to Curve Map"); + else + ur->create_action("Modify Curve Map",true); - ur->add_do_method(graph.ptr(),"curve_map_node_set_points",type,p_id,new_points); - ur->add_undo_method(graph.ptr(),"curve_map_node_set_points",type,p_id,old_points); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + ur->add_do_method(graph.ptr(),"curve_map_node_set_points",type,p_id,new_points); + ur->add_undo_method(graph.ptr(),"curve_map_node_set_points",type,p_id,old_points); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_input_name_changed(const String& p_name, int p_id, Node *p_line_edit) { - LineEdit *le=p_line_edit->cast_to(); - ERR_FAIL_COND(!le); + LineEdit *le=p_line_edit->cast_to(); + ERR_FAIL_COND(!le); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Input Name"); - ur->add_do_method(graph.ptr(),"input_node_set_name",type,p_id,p_name); - ur->add_undo_method(graph.ptr(),"input_node_set_name",type,p_id,graph->input_node_get_name(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; - le->set_text(graph->input_node_get_name(type,p_id)); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Input Name"); + ur->add_do_method(graph.ptr(),"input_node_set_name",type,p_id,p_name); + ur->add_undo_method(graph.ptr(),"input_node_set_name",type,p_id,graph->input_node_get_name(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; + le->set_text(graph->input_node_get_name(type,p_id)); } void ShaderGraphView::_tex_edited(int p_id,Node* p_button) { - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture"); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture"); } void ShaderGraphView::_cube_edited(int p_id,Node* p_button) { - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"); } @@ -1061,983 +1061,994 @@ void ShaderGraphView::_cube_edited(int p_id,Node* p_button) { void ShaderGraphView::_connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - int from_idx=-1; - int to_idx=-1; - for (Map::Element *E=node_map.front();E;E=E->next()) { + int from_idx=-1; + int to_idx=-1; + for (Map::Element *E=node_map.front();E;E=E->next()) { - if (p_from==E->get()->get_name()) - from_idx=E->key(); - if (p_to==E->get()->get_name()) - to_idx=E->key(); - } + if (p_from==E->get()->get_name()) + from_idx=E->key(); + if (p_to==E->get()->get_name()) + to_idx=E->key(); + } - ERR_FAIL_COND(from_idx==-1); - ERR_FAIL_COND(to_idx==-1); + ERR_FAIL_COND(from_idx==-1); + ERR_FAIL_COND(to_idx==-1); - ur->create_action("Connect Graph Nodes"); + ur->create_action("Connect Graph Nodes"); - List conns; + List conns; - graph->get_node_connections(type,&conns); - //disconnect/reconnect dependencies - ur->add_undo_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - for(List::Element *E=conns.front();E;E=E->next()) { + graph->get_node_connections(type,&conns); + //disconnect/reconnect dependencies + ur->add_undo_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + for(List::Element *E=conns.front();E;E=E->next()) { - if (E->get().dst_id==to_idx && E->get().dst_slot==p_to_slot) { - ur->add_do_method(graph.ptr(),"disconnect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); - ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); - } - } - ur->add_do_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + if (E->get().dst_id==to_idx && E->get().dst_slot==p_to_slot) { + ur->add_do_method(graph.ptr(),"disconnect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + } + } + ur->add_do_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - int from_idx=-1; - int to_idx=-1; - for (Map::Element *E=node_map.front();E;E=E->next()) { + int from_idx=-1; + int to_idx=-1; + for (Map::Element *E=node_map.front();E;E=E->next()) { - if (p_from==E->get()->get_name()) - from_idx=E->key(); - if (p_to==E->get()->get_name()) - to_idx=E->key(); - } + if (p_from==E->get()->get_name()) + from_idx=E->key(); + if (p_to==E->get()->get_name()) + to_idx=E->key(); + } - ERR_FAIL_COND(from_idx==-1); - ERR_FAIL_COND(to_idx==-1); + ERR_FAIL_COND(from_idx==-1); + ERR_FAIL_COND(to_idx==-1); - if (!graph->is_node_connected(type,from_idx,p_from_slot,to_idx,p_to_slot)) - return; //nothing to disconnect + if (!graph->is_node_connected(type,from_idx,p_from_slot,to_idx,p_to_slot)) + return; //nothing to disconnect - ur->create_action("Disconnect Graph Nodes"); + ur->create_action("Disconnect Graph Nodes"); - List conns; + List conns; - graph->get_node_connections(type,&conns); - //disconnect/reconnect dependencies - ur->add_do_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - ur->add_undo_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + graph->get_node_connections(type,&conns); + //disconnect/reconnect dependencies + ur->add_do_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_undo_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_node_removed(int p_id) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Remove Shader Graph Node"); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Remove Shader Graph Node"); - ur->add_do_method(graph.ptr(),"node_remove",type,p_id); - ur->add_undo_method(graph.ptr(),"node_add",type,graph->node_get_type(type,p_id),p_id); - ur->add_undo_method(graph.ptr(),"node_set_state",type,p_id,graph->node_get_state(type,p_id)); - List conns; + ur->add_do_method(graph.ptr(),"node_remove",type,p_id); + ur->add_undo_method(graph.ptr(),"node_add",type,graph->node_get_type(type,p_id),p_id); + ur->add_undo_method(graph.ptr(),"node_set_state",type,p_id,graph->node_get_state(type,p_id)); + List conns; - graph->get_node_connections(type,&conns); - for(List::Element *E=conns.front();E;E=E->next()) { + graph->get_node_connections(type,&conns); + for(List::Element *E=conns.front();E;E=E->next()) { - if (E->get().dst_id==p_id || E->get().src_id==p_id) { - ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); - } - } - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + if (E->get().dst_id==p_id || E->get().src_id==p_id) { + ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + } + } + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } +void ShaderGraphView::_begin_node_move() +{ + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Move Shader Graph Node"); +} + void ShaderGraphView::_node_moved(const Vector2& p_from, const Vector2& p_to,int p_id) { - ERR_FAIL_COND(!node_map.has(p_id)); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Move Shader Graph Node"); - ur->add_do_method(this,"_move_node",p_id,p_to); - ur->add_undo_method(this,"_move_node",p_id,p_from); - ur->commit_action(); + ERR_FAIL_COND(!node_map.has(p_id)); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->add_do_method(this,"_move_node",p_id,p_to); + ur->add_undo_method(this,"_move_node",p_id,p_from); +} + +void ShaderGraphView::_end_node_move() +{ + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->commit_action(); } void ShaderGraphView::_move_node(int p_id,const Vector2& p_to) { - ERR_FAIL_COND(!node_map.has(p_id)); - node_map[p_id]->set_offset(p_to); - graph->node_set_pos(type,p_id,p_to); + ERR_FAIL_COND(!node_map.has(p_id)); + node_map[p_id]->set_offset(p_to); + graph->node_set_pos(type,p_id,p_to); } void ShaderGraphView::_create_node(int p_id) { - GraphNode *gn = memnew( GraphNode ); - gn->set_show_close_button(true); - Color typecol[4]={ - Color(0.9,0.4,1), - Color(0.8,1,0.2), - Color(1,0.2,0.2), - Color(0,1,1) - }; - - - switch(graph->node_get_type(type,p_id)) { - - case ShaderGraph::NODE_INPUT: { - - gn->set_title("Input"); - - List si; - ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); - - int idx=0; - for (List::Element *E=si.front();E;E=E->next()) { - ShaderGraph::SlotInfo& s=E->get(); - if (s.dir==ShaderGraph::SLOT_IN) { - - Label *l= memnew( Label ); - l->set_text(s.name); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - gn->set_slot(idx,false,0,Color(),true,s.type,typecol[s.type]); - idx++; - } - } - - } break; // all inputs (case Shader type dependent) - case ShaderGraph::NODE_SCALAR_CONST: { - gn->set_title("Scalar"); - SpinBox *sb = memnew( SpinBox ); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->scalar_const_node_get_value(type,p_id)); - sb->connect("value_changed",this,"_scalar_const_changed",varray(p_id)); - gn->add_child(sb); - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; //scalar constant - case ShaderGraph::NODE_VEC_CONST: { - - gn->set_title("Vector"); - Array v3p(true); - for(int i=0;i<3;i++) { - HBoxContainer *hbc = memnew( HBoxContainer ); - Label *l = memnew( Label ); - l->set_text(String::chr('X'+i)); - hbc->add_child(l); - SpinBox *sb = memnew( SpinBox ); - sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->vec_const_node_get_value(type,p_id)[i]); - sb->connect("value_changed",this,"_vec_const_changed",varray(p_id,v3p)); - v3p.push_back(sb); - hbc->add_child(sb); - gn->add_child(hbc); - } - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; //vec3 constant - case ShaderGraph::NODE_RGB_CONST: { - - gn->set_title("Color"); - ColorPickerButton *cpb = memnew( ColorPickerButton ); - cpb->set_color(graph->rgb_const_node_get_value(type,p_id)); - cpb->connect("color_changed",this,"_rgb_const_changed",varray(p_id)); - gn->add_child(cpb); - Label *l = memnew( Label ); - l->set_text("RGB"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; //rgb constant (shows a color picker instead) - case ShaderGraph::NODE_XFORM_CONST: { - gn->set_title("XForm"); - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_xform_const_changed",varray(p_id,edit)); - gn->add_child(edit); - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - - } break; // 4x4 matrix constant - case ShaderGraph::NODE_TIME: { - - gn->set_title("Time"); - Label *l = memnew( Label ); - l->set_text("(s)"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // time in seconds - case ShaderGraph::NODE_SCREEN_TEX: { - - gn->set_title("ScreenTex"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("RGB"))); - gn->add_child(hbc); - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) - case ShaderGraph::NODE_SCALAR_OP: { - - gn->set_title("ScalarOp"); - static const char* op_name[ShaderGraph::SCALAR_MAX_OP]={ - "Add", - "Sub", - "Mul", - "Div", - "Mod", - "Pow", - "Max", - "Min", - "Atan2" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->scalar_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_scalar_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - - } break; // scalar vs scalar op (mul: { } break; add: { } break; div: { } break; etc) - case ShaderGraph::NODE_VEC_OP: { - - gn->set_title("VecOp"); - static const char* op_name[ShaderGraph::VEC_MAX_OP]={ - "Add", - "Sub", - "Mul", - "Div", - "Mod", - "Pow", - "Max", - "Min", - "Cross" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->vec_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_vec_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - - } break; // vec3 vs vec3 op (mul: { } break;ad: { } break;div: { } break;crossprod: { } break;etc) - case ShaderGraph::NODE_VEC_SCALAR_OP: { - - gn->set_title("VecScalarOp"); - static const char* op_name[ShaderGraph::VEC_SCALAR_MAX_OP]={ - "Mul", - "Div", - "Pow", - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->vec_scalar_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_vec_scalar_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - - } break; // vec3 vs scalar op (mul: { } break; add: { } break; div: { } break; etc) - case ShaderGraph::NODE_RGB_OP: { - - gn->set_title("RGB Op"); - static const char* op_name[ShaderGraph::RGB_MAX_OP]={ - "Screen", - "Difference", - "Darken", - "Lighten", - "Overlay", - "Dodge", - "Burn", - "SoftLight", - "HardLight" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->rgb_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_rgb_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; // vec3 vs vec3 rgb op (with scalar amount): { } break; like brighten: { } break; darken: { } break; burn: { } break; dodge: { } break; multiply: { } break; etc. - case ShaderGraph::NODE_XFORM_MULT: { - - gn->set_title("XFMult"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color()); - - - } break; // mat4 x mat4 - case ShaderGraph::NODE_XFORM_VEC_MULT: { - - gn->set_title("XFVecMult"); - - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); - button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); - button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); - - gn->add_child(button); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); - hbc->add_spacer(); - Label *l = memnew(Label("out")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - gn->add_child( memnew(Label("vec"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; - case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { - - gn->set_title("XFVecInvMult"); - - - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); - button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); - button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); - - gn->add_child(button); - - gn->add_child( memnew(Label("vec"))); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); - hbc->add_spacer(); - Label *l = memnew(Label("out")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - - } break; // mat4 x vec3 inverse mult (with no-translation option) - case ShaderGraph::NODE_SCALAR_FUNC: { - - gn->set_title("ScalarFunc"); - static const char* func_name[ShaderGraph::SCALAR_MAX_FUNC]={ - "Sin", - "Cos", - "Tan", - "ASin", - "ACos", - "ATan", - "SinH", - "CosH", - "TanH", - "Log", - "Exp", - "Sqrt", - "Abs", - "Sign", - "Floor", - "Round", - "Ceil", - "Frac", - "Satr", - "Neg" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(func_name[i],i); - } - - ob->select(graph->scalar_func_node_get_function(type,p_id)); - ob->connect("item_selected",this,"_scalar_func_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // scalar function (sin: { } break; cos: { } break; etc) - case ShaderGraph::NODE_VEC_FUNC: { - - - - gn->set_title("VecFunc"); - static const char* func_name[ShaderGraph::VEC_MAX_FUNC]={ - "Normalize", - "Saturate", - "Negate", - "Reciprocal", - "RGB to HSV", - "HSV to RGB", - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(func_name[i],i); - } - - ob->select(graph->vec_func_node_get_function(type,p_id)); - ob->connect("item_selected",this,"_vec_func_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("in"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // vector function (normalize: { } break; negate: { } break; reciprocal: { } break; rgb2hsv: { } break; hsv2rgb: { } break; etc: { } break; etc) - case ShaderGraph::NODE_VEC_LEN: { - gn->set_title("VecLength"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("len"))); - gn->add_child(hbc); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // vec3 length - case ShaderGraph::NODE_DOT_PROD: { - - gn->set_title("DotProduct"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("dp"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; // vec3 . vec3 (dot product -> scalar output) - case ShaderGraph::NODE_VEC_TO_SCALAR: { - - gn->set_title("Vec2Scalar"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("vec"))); - hbc->add_spacer(); - Label *l=memnew(Label("x")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - l=memnew(Label("y")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l ); - l=memnew(Label("z")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - - - } break; // 1 vec3 input: { } break; 3 scalar outputs - case ShaderGraph::NODE_SCALAR_TO_VEC: { - - gn->set_title("Scalar2Vec"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("x"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("vec"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - } break; // 3 scalar input: { } break; 1 vec3 output - case ShaderGraph::NODE_VEC_TO_XFORM: { - - gn->set_title("Vec2XForm"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("x"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("xf"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); - gn->add_child( memnew(Label("ofs"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; // 3 vec input: { } break; 1 xform output - case ShaderGraph::NODE_XFORM_TO_VEC: { - - gn->set_title("XForm2Vec"); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); - hbc->add_spacer(); - Label *l=memnew(Label("x")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - l=memnew(Label("y")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l ); - l=memnew(Label("z")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - l=memnew(Label("ofs")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // 3 vec input: { } break; 1 xform output - case ShaderGraph::NODE_SCALAR_INTERP: { - - gn->set_title("ScalarInterp"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("interp"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - - } break; // scalar interpolation (with optional curve) - case ShaderGraph::NODE_VEC_INTERP: { - - gn->set_title("VecInterp"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("interp"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); + GraphNode *gn = memnew( GraphNode ); + gn->set_show_close_button(true); + Color typecol[4]={ + Color(0.9,0.4,1), + Color(0.8,1,0.2), + Color(1,0.2,0.2), + Color(0,1,1) + }; + + + switch(graph->node_get_type(type,p_id)) { + + case ShaderGraph::NODE_INPUT: { + + gn->set_title("Input"); + + List si; + ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); + + int idx=0; + for (List::Element *E=si.front();E;E=E->next()) { + ShaderGraph::SlotInfo& s=E->get(); + if (s.dir==ShaderGraph::SLOT_IN) { + + Label *l= memnew( Label ); + l->set_text(s.name); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + gn->set_slot(idx,false,0,Color(),true,s.type,typecol[s.type]); + idx++; + } + } + + } break; // all inputs (case Shader type dependent) + case ShaderGraph::NODE_SCALAR_CONST: { + gn->set_title("Scalar"); + SpinBox *sb = memnew( SpinBox ); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->scalar_const_node_get_value(type,p_id)); + sb->connect("value_changed",this,"_scalar_const_changed",varray(p_id)); + gn->add_child(sb); + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; //scalar constant + case ShaderGraph::NODE_VEC_CONST: { + + gn->set_title("Vector"); + Array v3p(true); + for(int i=0;i<3;i++) { + HBoxContainer *hbc = memnew( HBoxContainer ); + Label *l = memnew( Label ); + l->set_text(String::chr('X'+i)); + hbc->add_child(l); + SpinBox *sb = memnew( SpinBox ); + sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->vec_const_node_get_value(type,p_id)[i]); + sb->connect("value_changed",this,"_vec_const_changed",varray(p_id,v3p)); + v3p.push_back(sb); + hbc->add_child(sb); + gn->add_child(hbc); + } + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; //vec3 constant + case ShaderGraph::NODE_RGB_CONST: { + + gn->set_title("Color"); + ColorPickerButton *cpb = memnew( ColorPickerButton ); + cpb->set_color(graph->rgb_const_node_get_value(type,p_id)); + cpb->connect("color_changed",this,"_rgb_const_changed",varray(p_id)); + gn->add_child(cpb); + Label *l = memnew( Label ); + l->set_text("RGB"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; //rgb constant (shows a color picker instead) + case ShaderGraph::NODE_XFORM_CONST: { + gn->set_title("XForm"); + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_xform_const_changed",varray(p_id,edit)); + gn->add_child(edit); + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + + } break; // 4x4 matrix constant + case ShaderGraph::NODE_TIME: { + + gn->set_title("Time"); + Label *l = memnew( Label ); + l->set_text("(s)"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // time in seconds + case ShaderGraph::NODE_SCREEN_TEX: { + + gn->set_title("ScreenTex"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("RGB"))); + gn->add_child(hbc); + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) + case ShaderGraph::NODE_SCALAR_OP: { + + gn->set_title("ScalarOp"); + static const char* op_name[ShaderGraph::SCALAR_MAX_OP]={ + "Add", + "Sub", + "Mul", + "Div", + "Mod", + "Pow", + "Max", + "Min", + "Atan2" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->scalar_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_scalar_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + + } break; // scalar vs scalar op (mul: { } break; add: { } break; div: { } break; etc) + case ShaderGraph::NODE_VEC_OP: { + + gn->set_title("VecOp"); + static const char* op_name[ShaderGraph::VEC_MAX_OP]={ + "Add", + "Sub", + "Mul", + "Div", + "Mod", + "Pow", + "Max", + "Min", + "Cross" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->vec_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_vec_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + + } break; // vec3 vs vec3 op (mul: { } break;ad: { } break;div: { } break;crossprod: { } break;etc) + case ShaderGraph::NODE_VEC_SCALAR_OP: { + + gn->set_title("VecScalarOp"); + static const char* op_name[ShaderGraph::VEC_SCALAR_MAX_OP]={ + "Mul", + "Div", + "Pow", + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->vec_scalar_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_vec_scalar_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + + } break; // vec3 vs scalar op (mul: { } break; add: { } break; div: { } break; etc) + case ShaderGraph::NODE_RGB_OP: { + + gn->set_title("RGB Op"); + static const char* op_name[ShaderGraph::RGB_MAX_OP]={ + "Screen", + "Difference", + "Darken", + "Lighten", + "Overlay", + "Dodge", + "Burn", + "SoftLight", + "HardLight" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->rgb_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_rgb_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; // vec3 vs vec3 rgb op (with scalar amount): { } break; like brighten: { } break; darken: { } break; burn: { } break; dodge: { } break; multiply: { } break; etc. + case ShaderGraph::NODE_XFORM_MULT: { + + gn->set_title("XFMult"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color()); + + + } break; // mat4 x mat4 + case ShaderGraph::NODE_XFORM_VEC_MULT: { + + gn->set_title("XFVecMult"); + + Button *button = memnew( Button("RotOnly")); + button->set_toggle_mode(true); + button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); + button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); + + gn->add_child(button); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l = memnew(Label("out")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + gn->add_child( memnew(Label("vec"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; + case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { + + gn->set_title("XFVecInvMult"); + + + Button *button = memnew( Button("RotOnly")); + button->set_toggle_mode(true); + button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); + button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); + + gn->add_child(button); + + gn->add_child( memnew(Label("vec"))); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l = memnew(Label("out")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + + } break; // mat4 x vec3 inverse mult (with no-translation option) + case ShaderGraph::NODE_SCALAR_FUNC: { + + gn->set_title("ScalarFunc"); + static const char* func_name[ShaderGraph::SCALAR_MAX_FUNC]={ + "Sin", + "Cos", + "Tan", + "ASin", + "ACos", + "ATan", + "SinH", + "CosH", + "TanH", + "Log", + "Exp", + "Sqrt", + "Abs", + "Sign", + "Floor", + "Round", + "Ceil", + "Frac", + "Satr", + "Neg" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(func_name[i],i); + } + + ob->select(graph->scalar_func_node_get_function(type,p_id)); + ob->connect("item_selected",this,"_scalar_func_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("in"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar function (sin: { } break; cos: { } break; etc) + case ShaderGraph::NODE_VEC_FUNC: { + + + + gn->set_title("VecFunc"); + static const char* func_name[ShaderGraph::VEC_MAX_FUNC]={ + "Normalize", + "Saturate", + "Negate", + "Reciprocal", + "RGB to HSV", + "HSV to RGB", + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(func_name[i],i); + } + + ob->select(graph->vec_func_node_get_function(type,p_id)); + ob->connect("item_selected",this,"_vec_func_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("in"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // vector function (normalize: { } break; negate: { } break; reciprocal: { } break; rgb2hsv: { } break; hsv2rgb: { } break; etc: { } break; etc) + case ShaderGraph::NODE_VEC_LEN: { + gn->set_title("VecLength"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("in"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("len"))); + gn->add_child(hbc); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // vec3 length + case ShaderGraph::NODE_DOT_PROD: { + + gn->set_title("DotProduct"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("dp"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; // vec3 . vec3 (dot product -> scalar output) + case ShaderGraph::NODE_VEC_TO_SCALAR: { + + gn->set_title("Vec2Scalar"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("vec"))); + hbc->add_spacer(); + Label *l=memnew(Label("x")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("y")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l ); + l=memnew(Label("z")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + + + } break; // 1 vec3 input: { } break; 3 scalar outputs + case ShaderGraph::NODE_SCALAR_TO_VEC: { + + gn->set_title("Scalar2Vec"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("x"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("vec"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("y"))); + gn->add_child( memnew(Label("z"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + } break; // 3 scalar input: { } break; 1 vec3 output + case ShaderGraph::NODE_VEC_TO_XFORM: { + + gn->set_title("Vec2XForm"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("x"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("xf"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("y"))); + gn->add_child( memnew(Label("z"))); + gn->add_child( memnew(Label("ofs"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; // 3 vec input: { } break; 1 xform output + case ShaderGraph::NODE_XFORM_TO_VEC: { + + gn->set_title("XForm2Vec"); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l=memnew(Label("x")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("y")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l ); + l=memnew(Label("z")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + l=memnew(Label("ofs")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // 3 vec input: { } break; 1 xform output + case ShaderGraph::NODE_SCALAR_INTERP: { + + gn->set_title("ScalarInterp"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("interp"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + gn->add_child( memnew(Label("c"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + + } break; // scalar interpolation (with optional curve) + case ShaderGraph::NODE_VEC_INTERP: { + + gn->set_title("VecInterp"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("interp"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + gn->add_child( memnew(Label("c"))); - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - } break; // vec3 interpolation (with optional curve) - case ShaderGraph::NODE_COLOR_RAMP: { - - gn->set_title("ColorRamp"); - GraphColorRampEdit * ramp = memnew( GraphColorRampEdit ); - - DVector offsets = graph->color_ramp_node_get_offsets(type,p_id); - DVector colors = graph->color_ramp_node_get_colors(type,p_id); - - int oc = offsets.size(); - - if (oc) { - DVector::Read rofs = offsets.read(); - DVector::Read rcol = colors.read(); - - Vector ofsv; - Vector colorv; - for(int i=0;iset_ramp(ofsv,colorv); - - } - - ramp->connect("ramp_changed",this,"_color_ramp_changed",varray(p_id,ramp)); - ramp->set_custom_minimum_size(Size2(128,1)); - gn->add_child(ramp); - - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); - hbc->add_spacer(); - Label *l=memnew(Label("rgb")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - l=memnew(Label("alpha")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,false,ShaderGraph::SLOT_MAX,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // scalar interpolation (with optional curve) - case ShaderGraph::NODE_CURVE_MAP: { - - gn->set_title("CurveMap"); - GraphCurveMapEdit * map = memnew( GraphCurveMapEdit ); - - DVector points = graph->curve_map_node_get_points(type,p_id); - - int oc = points.size(); - - if (oc) { - DVector::Read rofs = points.read(); - - - Vector ofsv; - for(int i=0;iset_points(ofsv); - - } - map->connect("curve_changed",this,"_curve_changed",varray(p_id,map)); - - //map->connect("map_changed",this,"_curve_map_changed",varray(p_id,map)); - map->set_custom_minimum_size(Size2(128,64)); - gn->add_child(map); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); - hbc->add_spacer(); - Label *l=memnew(Label("cmap")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // scalar interpolation (with optional curve) - - case ShaderGraph::NODE_SCALAR_INPUT: { - - gn->set_title("ScalarUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - SpinBox *sb = memnew( SpinBox ); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->scalar_input_node_get_value(type,p_id)); - sb->connect("value_changed",this,"_scalar_input_changed",varray(p_id)); - gn->add_child(sb); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // scalar uniform (assignable in material) - case ShaderGraph::NODE_VEC_INPUT: { - - gn->set_title("VectorUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - Array v3p(true); - for(int i=0;i<3;i++) { - HBoxContainer *hbc = memnew( HBoxContainer ); - Label *l = memnew( Label ); - l->set_text(String::chr('X'+i)); - hbc->add_child(l); - SpinBox *sb = memnew( SpinBox ); - sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->vec_input_node_get_value(type,p_id)[i]); - sb->connect("value_changed",this,"_vec_input_changed",varray(p_id,v3p)); - v3p.push_back(sb); - hbc->add_child(sb); - gn->add_child(hbc); - } - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // vec3 uniform (assignable in material) - case ShaderGraph::NODE_RGB_INPUT: { - - gn->set_title("ColorUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - ColorPickerButton *cpb = memnew( ColorPickerButton ); - cpb->set_color(graph->rgb_input_node_get_value(type,p_id)); - cpb->connect("color_changed",this,"_rgb_input_changed",varray(p_id)); - gn->add_child(cpb); - Label *l = memnew( Label ); - l->set_text("RGB"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // color uniform (assignable in material) - case ShaderGraph::NODE_XFORM_INPUT: { - gn->set_title("XFUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_xform_input_changed",varray(p_id,edit)); - gn->add_child(edit); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - - } break; // mat4 uniform (assignable in material) - case ShaderGraph::NODE_TEXTURE_INPUT: { - - gn->set_title("TexUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - TextureFrame *tex = memnew( TextureFrame ); - tex->set_expand(true); - tex->set_custom_minimum_size(Size2(80,80)); - gn->add_child(tex); - tex->set_texture(graph->texture_input_node_get_value(type,p_id)); - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_tex_edited",varray(p_id,edit)); - gn->add_child(edit); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - Label *l=memnew(Label("RGB")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child(l); - gn->add_child(hbc); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(4,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // texture input (assignable in material) - case ShaderGraph::NODE_CUBEMAP_INPUT: { - - gn->set_title("TexUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_cube_edited",varray(p_id,edit)); - gn->add_child(edit); - - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - Label *l=memnew(Label("RGB")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child(l); - gn->add_child(hbc); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // cubemap input (assignable in material) - case ShaderGraph::NODE_DEFAULT_TEXTURE: { - - gn->set_title("CanvasItemTex"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - Label *l=memnew(Label("RGB")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child(l); - gn->add_child(hbc); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) - - case ShaderGraph::NODE_OUTPUT: { - gn->set_title("Output"); - - List si; - ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); - - int idx=0; - for (List::Element *E=si.front();E;E=E->next()) { - ShaderGraph::SlotInfo& s=E->get(); - if (s.dir==ShaderGraph::SLOT_OUT) { - - Label *l= memnew( Label ); - l->set_text(s.name); - l->set_align(Label::ALIGN_LEFT); - gn->add_child(l); - gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); - idx++; - } - } - - } break; // output (case Shader type dependent) - case ShaderGraph::NODE_COMMENT: { - gn->set_title("Comment"); - TextEdit *te = memnew(TextEdit); - te->set_custom_minimum_size(Size2(100,100)); - gn->add_child(te); - te->set_text(graph->comment_node_get_text(type,p_id)); - te->connect("text_changed",this,"_comment_edited",varray(p_id,te)); - - } break; // comment - - - - } - - gn->connect("dragged",this,"_node_moved",varray(p_id)); - gn->connect("close_request",this,"_node_removed",varray(p_id),CONNECT_DEFERRED); - graph_edit->add_child(gn); - node_map[p_id]=gn; - gn->set_offset(graph->node_get_pos(type,p_id)); + } break; // vec3 interpolation (with optional curve) + case ShaderGraph::NODE_COLOR_RAMP: { + + gn->set_title("ColorRamp"); + GraphColorRampEdit * ramp = memnew( GraphColorRampEdit ); + + DVector offsets = graph->color_ramp_node_get_offsets(type,p_id); + DVector colors = graph->color_ramp_node_get_colors(type,p_id); + + int oc = offsets.size(); + + if (oc) { + DVector::Read rofs = offsets.read(); + DVector::Read rcol = colors.read(); + + Vector ofsv; + Vector colorv; + for(int i=0;iset_ramp(ofsv,colorv); + + } + + ramp->connect("ramp_changed",this,"_color_ramp_changed",varray(p_id,ramp)); + ramp->set_custom_minimum_size(Size2(128,1)); + gn->add_child(ramp); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("c"))); + hbc->add_spacer(); + Label *l=memnew(Label("rgb")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("alpha")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,ShaderGraph::SLOT_MAX,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar interpolation (with optional curve) + case ShaderGraph::NODE_CURVE_MAP: { + + gn->set_title("CurveMap"); + GraphCurveMapEdit * map = memnew( GraphCurveMapEdit ); + + DVector points = graph->curve_map_node_get_points(type,p_id); + + int oc = points.size(); + + if (oc) { + DVector::Read rofs = points.read(); + + + Vector ofsv; + for(int i=0;iset_points(ofsv); + + } + map->connect("curve_changed",this,"_curve_changed",varray(p_id,map)); + + //map->connect("map_changed",this,"_curve_map_changed",varray(p_id,map)); + map->set_custom_minimum_size(Size2(128,64)); + gn->add_child(map); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("c"))); + hbc->add_spacer(); + Label *l=memnew(Label("cmap")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar interpolation (with optional curve) + + case ShaderGraph::NODE_SCALAR_INPUT: { + + gn->set_title("ScalarUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + SpinBox *sb = memnew( SpinBox ); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->scalar_input_node_get_value(type,p_id)); + sb->connect("value_changed",this,"_scalar_input_changed",varray(p_id)); + gn->add_child(sb); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // scalar uniform (assignable in material) + case ShaderGraph::NODE_VEC_INPUT: { + + gn->set_title("VectorUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + Array v3p(true); + for(int i=0;i<3;i++) { + HBoxContainer *hbc = memnew( HBoxContainer ); + Label *l = memnew( Label ); + l->set_text(String::chr('X'+i)); + hbc->add_child(l); + SpinBox *sb = memnew( SpinBox ); + sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->vec_input_node_get_value(type,p_id)[i]); + sb->connect("value_changed",this,"_vec_input_changed",varray(p_id,v3p)); + v3p.push_back(sb); + hbc->add_child(sb); + gn->add_child(hbc); + } + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // vec3 uniform (assignable in material) + case ShaderGraph::NODE_RGB_INPUT: { + + gn->set_title("ColorUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + ColorPickerButton *cpb = memnew( ColorPickerButton ); + cpb->set_color(graph->rgb_input_node_get_value(type,p_id)); + cpb->connect("color_changed",this,"_rgb_input_changed",varray(p_id)); + gn->add_child(cpb); + Label *l = memnew( Label ); + l->set_text("RGB"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // color uniform (assignable in material) + case ShaderGraph::NODE_XFORM_INPUT: { + gn->set_title("XFUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_xform_input_changed",varray(p_id,edit)); + gn->add_child(edit); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + + } break; // mat4 uniform (assignable in material) + case ShaderGraph::NODE_TEXTURE_INPUT: { + + gn->set_title("TexUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + TextureFrame *tex = memnew( TextureFrame ); + tex->set_expand(true); + tex->set_custom_minimum_size(Size2(80,80)); + gn->add_child(tex); + tex->set_texture(graph->texture_input_node_get_value(type,p_id)); + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_tex_edited",varray(p_id,edit)); + gn->add_child(edit); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(4,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // texture input (assignable in material) + case ShaderGraph::NODE_CUBEMAP_INPUT: { + + gn->set_title("TexUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_cube_edited",varray(p_id,edit)); + gn->add_child(edit); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // cubemap input (assignable in material) + case ShaderGraph::NODE_DEFAULT_TEXTURE: { + + gn->set_title("CanvasItemTex"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) + + case ShaderGraph::NODE_OUTPUT: { + gn->set_title("Output"); + gn->set_show_close_button(false); + + List si; + ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); + + int idx=0; + for (List::Element *E=si.front();E;E=E->next()) { + ShaderGraph::SlotInfo& s=E->get(); + if (s.dir==ShaderGraph::SLOT_OUT) { + + Label *l= memnew( Label ); + l->set_text(s.name); + l->set_align(Label::ALIGN_LEFT); + gn->add_child(l); + gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); + idx++; + } + } + + } break; // output (case Shader type dependent) + case ShaderGraph::NODE_COMMENT: { + gn->set_title("Comment"); + TextEdit *te = memnew(TextEdit); + te->set_custom_minimum_size(Size2(100,100)); + gn->add_child(te); + te->set_text(graph->comment_node_get_text(type,p_id)); + te->connect("text_changed",this,"_comment_edited",varray(p_id,te)); + + } break; // comment + + + + } + + gn->connect("dragged",this,"_node_moved",varray(p_id)); + gn->connect("close_request",this,"_node_removed",varray(p_id),CONNECT_DEFERRED); + graph_edit->add_child(gn); + node_map[p_id]=gn; + gn->set_offset(graph->node_get_pos(type,p_id)); } @@ -2045,36 +2056,36 @@ void ShaderGraphView::_create_node(int p_id) { void ShaderGraphView::_update_graph() { - if (block_update) - return; + if (block_update) + return; - for (Map::Element *E=node_map.front();E;E=E->next()) { + for (Map::Element *E=node_map.front();E;E=E->next()) { - memdelete(E->get()); - } + memdelete(E->get()); + } - node_map.clear(); + node_map.clear(); - if (!graph.is_valid()) - return; + if (!graph.is_valid()) + return; - List nl; - graph->get_node_list(type,&nl); + List nl; + graph->get_node_list(type,&nl); - for(List::Element *E=nl.front();E;E=E->next()) { + for(List::Element *E=nl.front();E;E=E->next()) { - _create_node(E->get()); - } - graph_edit->clear_connections(); + _create_node(E->get()); + } + graph_edit->clear_connections(); - List connections; - graph->get_node_connections(type,&connections); - for(List::Element *E=connections.front();E;E=E->next()) { + List connections; + graph->get_node_connections(type,&connections); + for(List::Element *E=connections.front();E;E=E->next()) { - ERR_CONTINUE(!node_map.has(E->get().src_id) || !node_map.has(E->get().dst_id)); - graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot); - } + ERR_CONTINUE(!node_map.has(E->get().src_id) || !node_map.has(E->get().dst_id)); + graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot); + } @@ -2082,305 +2093,309 @@ void ShaderGraphView::_update_graph() { void ShaderGraphView::_sg_updated() { - if (!graph.is_valid()) - return; - switch(graph->get_graph_error(type)) { - case ShaderGraph::GRAPH_OK: status->set_text(""); break; - case ShaderGraph::GRAPH_ERROR_CYCLIC: status->set_text("Error: Cyclic Connection Link"); break; - case ShaderGraph::GRAPH_ERROR_MISSING_CONNECTIONS: status->set_text("Error: Missing Input Connections"); break; - } + if (!graph.is_valid()) + return; + switch(graph->get_graph_error(type)) { + case ShaderGraph::GRAPH_OK: status->set_text(""); break; + case ShaderGraph::GRAPH_ERROR_CYCLIC: status->set_text("Error: Cyclic Connection Link"); break; + case ShaderGraph::GRAPH_ERROR_MISSING_CONNECTIONS: status->set_text("Error: Missing Input Connections"); break; + } } void ShaderGraphView::set_graph(Ref p_graph){ - if (graph.is_valid()) { - graph->disconnect("updated",this,"_sg_updated"); - } - graph=p_graph; - if (graph.is_valid()) { - graph->connect("updated",this,"_sg_updated"); - } - _update_graph(); - _sg_updated(); + if (graph.is_valid()) { + graph->disconnect("updated",this,"_sg_updated"); + } + graph=p_graph; + if (graph.is_valid()) { + graph->connect("updated",this,"_sg_updated"); + } + _update_graph(); + _sg_updated(); } void ShaderGraphView::_notification(int p_what) { - if (p_what==NOTIFICATION_ENTER_TREE) { + if (p_what==NOTIFICATION_ENTER_TREE) { - ped_popup->connect("variant_changed",this,"_variant_edited"); - } + ped_popup->connect("variant_changed",this,"_variant_edited"); + } } void ShaderGraphView::add_node(int p_type, const Vector2 &location) { - List existing; - graph->get_node_list(type,&existing); - existing.sort(); - int newid=1; - for(List::Element *E=existing.front();E;E=E->next()) { - if (!E->next() || (E->get()+1!=E->next()->get())){ - newid=E->get()+1; - break; - } - } - - Vector2 init_ofs = location; - while(true) { - bool valid=true; - for(List::Element *E=existing.front();E;E=E->next()) { - Vector2 pos = graph->node_get_pos(type,E->get()); - if (init_ofs==pos) { - init_ofs+=Vector2(20,20); - valid=false; - break; - - } - } - - if (valid) - break; - } - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Add Shader Graph Node"); - ur->add_do_method(graph.ptr(),"node_add",type,p_type,newid); - ur->add_do_method(graph.ptr(),"node_set_pos",type,newid,init_ofs); - ur->add_undo_method(graph.ptr(),"node_remove",type,newid); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + List existing; + graph->get_node_list(type,&existing); + existing.sort(); + int newid=1; + for(List::Element *E=existing.front();E;E=E->next()) { + if (!E->next() || (E->get()+1!=E->next()->get())){ + newid=E->get()+1; + break; + } + } + + Vector2 init_ofs = location; + while(true) { + bool valid=true; + for(List::Element *E=existing.front();E;E=E->next()) { + Vector2 pos = graph->node_get_pos(type,E->get()); + if (init_ofs==pos) { + init_ofs+=Vector2(20,20); + valid=false; + break; + + } + } + + if (valid) + break; + } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Add Shader Graph Node"); + ur->add_do_method(graph.ptr(),"node_add",type,p_type,newid); + ur->add_do_method(graph.ptr(),"node_set_pos",type,newid,init_ofs); + ur->add_undo_method(graph.ptr(),"node_remove",type,newid); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_bind_methods() { - ObjectTypeDB::bind_method("_update_graph",&ShaderGraphView::_update_graph); - ObjectTypeDB::bind_method("_node_moved",&ShaderGraphView::_node_moved); - ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node); - ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed); - ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request); - ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); - - ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); - ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); - ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed); - ObjectTypeDB::bind_method("_xform_const_changed",&ShaderGraphView::_xform_const_changed); - ObjectTypeDB::bind_method("_scalar_op_changed",&ShaderGraphView::_scalar_op_changed); - ObjectTypeDB::bind_method("_vec_op_changed",&ShaderGraphView::_vec_op_changed); - ObjectTypeDB::bind_method("_vec_scalar_op_changed",&ShaderGraphView::_vec_scalar_op_changed); - ObjectTypeDB::bind_method("_rgb_op_changed",&ShaderGraphView::_rgb_op_changed); - ObjectTypeDB::bind_method("_xform_inv_rev_changed",&ShaderGraphView::_xform_inv_rev_changed); - ObjectTypeDB::bind_method("_scalar_func_changed",&ShaderGraphView::_scalar_func_changed); - ObjectTypeDB::bind_method("_vec_func_changed",&ShaderGraphView::_vec_func_changed); - ObjectTypeDB::bind_method("_scalar_input_changed",&ShaderGraphView::_scalar_input_changed); - ObjectTypeDB::bind_method("_vec_input_changed",&ShaderGraphView::_vec_input_changed); - ObjectTypeDB::bind_method("_xform_input_changed",&ShaderGraphView::_xform_input_changed); - ObjectTypeDB::bind_method("_rgb_input_changed",&ShaderGraphView::_rgb_input_changed); - ObjectTypeDB::bind_method("_tex_input_change",&ShaderGraphView::_tex_input_change); - ObjectTypeDB::bind_method("_cube_input_change",&ShaderGraphView::_cube_input_change); - ObjectTypeDB::bind_method("_input_name_changed",&ShaderGraphView::_input_name_changed); - ObjectTypeDB::bind_method("_tex_edited",&ShaderGraphView::_tex_edited); - ObjectTypeDB::bind_method("_variant_edited",&ShaderGraphView::_variant_edited); - ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited); - ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited); - ObjectTypeDB::bind_method("_color_ramp_changed",&ShaderGraphView::_color_ramp_changed); - ObjectTypeDB::bind_method("_curve_changed",&ShaderGraphView::_curve_changed); - - ObjectTypeDB::bind_method("_sg_updated",&ShaderGraphView::_sg_updated); + ObjectTypeDB::bind_method("_update_graph",&ShaderGraphView::_update_graph); + ObjectTypeDB::bind_method("_begin_node_move", &ShaderGraphView::_begin_node_move); + ObjectTypeDB::bind_method("_node_moved",&ShaderGraphView::_node_moved); + ObjectTypeDB::bind_method("_end_node_move", &ShaderGraphView::_end_node_move); + ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node); + ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed); + ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request); + ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); + + ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); + ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); + ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed); + ObjectTypeDB::bind_method("_xform_const_changed",&ShaderGraphView::_xform_const_changed); + ObjectTypeDB::bind_method("_scalar_op_changed",&ShaderGraphView::_scalar_op_changed); + ObjectTypeDB::bind_method("_vec_op_changed",&ShaderGraphView::_vec_op_changed); + ObjectTypeDB::bind_method("_vec_scalar_op_changed",&ShaderGraphView::_vec_scalar_op_changed); + ObjectTypeDB::bind_method("_rgb_op_changed",&ShaderGraphView::_rgb_op_changed); + ObjectTypeDB::bind_method("_xform_inv_rev_changed",&ShaderGraphView::_xform_inv_rev_changed); + ObjectTypeDB::bind_method("_scalar_func_changed",&ShaderGraphView::_scalar_func_changed); + ObjectTypeDB::bind_method("_vec_func_changed",&ShaderGraphView::_vec_func_changed); + ObjectTypeDB::bind_method("_scalar_input_changed",&ShaderGraphView::_scalar_input_changed); + ObjectTypeDB::bind_method("_vec_input_changed",&ShaderGraphView::_vec_input_changed); + ObjectTypeDB::bind_method("_xform_input_changed",&ShaderGraphView::_xform_input_changed); + ObjectTypeDB::bind_method("_rgb_input_changed",&ShaderGraphView::_rgb_input_changed); + ObjectTypeDB::bind_method("_tex_input_change",&ShaderGraphView::_tex_input_change); + ObjectTypeDB::bind_method("_cube_input_change",&ShaderGraphView::_cube_input_change); + ObjectTypeDB::bind_method("_input_name_changed",&ShaderGraphView::_input_name_changed); + ObjectTypeDB::bind_method("_tex_edited",&ShaderGraphView::_tex_edited); + ObjectTypeDB::bind_method("_variant_edited",&ShaderGraphView::_variant_edited); + ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited); + ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited); + ObjectTypeDB::bind_method("_color_ramp_changed",&ShaderGraphView::_color_ramp_changed); + ObjectTypeDB::bind_method("_curve_changed",&ShaderGraphView::_curve_changed); + + ObjectTypeDB::bind_method("_sg_updated",&ShaderGraphView::_sg_updated); } ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) { - type=p_type; - graph_edit = memnew( GraphEdit ); - block_update=false; - ped_popup = memnew( CustomPropertyEditor ); - graph_edit->add_child(ped_popup); - status = memnew( Label ); - graph_edit->get_top_layer()->add_child(status); - status->set_pos(Vector2(5,5)); - status->add_color_override("font_color_shadow",Color(0,0,0)); - status->add_color_override("font_color",Color(1,0.4,0.3)); - status->add_constant_override("shadow_as_outline",1); - status->add_constant_override("shadow_offset_x",2); - status->add_constant_override("shadow_offset_y",2); - status->set_text(""); + type=p_type; + graph_edit = memnew( GraphEdit ); + block_update=false; + ped_popup = memnew( CustomPropertyEditor ); + graph_edit->add_child(ped_popup); + status = memnew( Label ); + graph_edit->get_top_layer()->add_child(status); + graph_edit->connect("_begin_node_move", this, "_begin_node_move"); + graph_edit->connect("_end_node_move", this, "_end_node_move"); + status->set_pos(Vector2(5,5)); + status->add_color_override("font_color_shadow",Color(0,0,0)); + status->add_color_override("font_color",Color(1,0.4,0.3)); + status->add_constant_override("shadow_as_outline",1); + status->add_constant_override("shadow_offset_x",2); + status->add_constant_override("shadow_offset_y",2); + status->set_text(""); } //////////////edit////////////// void ShaderGraphEditor::edit(Ref p_shader) { - for(int i=0;iset_graph(p_shader); - } + for(int i=0;iset_graph(p_shader); + } } void ShaderGraphEditor::_add_node(int p_type) { - ShaderGraph::ShaderType shader_type=ShaderGraph::ShaderType(tabs->get_current_tab()); + ShaderGraph::ShaderType shader_type=ShaderGraph::ShaderType(tabs->get_current_tab()); - graph_edits[shader_type]->add_node(p_type, next_location); + graph_edits[shader_type]->add_node(p_type, next_location); } void ShaderGraphEditor::_popup_requested(const Vector2 &p_position) { - next_location = get_local_mouse_pos(); - popup->set_global_pos(p_position); - popup->set_size( Size2( 200, 0) ); - popup->popup(); - popup->call_deferred("grab_click_focus"); - popup->set_invalidate_click_until_motion(); + next_location = get_local_mouse_pos(); + popup->set_global_pos(p_position); + popup->set_size( Size2( 200, 0) ); + popup->popup(); + popup->call_deferred("grab_click_focus"); + popup->set_invalidate_click_until_motion(); } void ShaderGraphEditor::_notification(int p_what) { - if (p_what==NOTIFICATION_ENTER_TREE) { + if (p_what==NOTIFICATION_ENTER_TREE) { - for(int i=0;iadd_icon_item(get_icon(ic,"EditorIcons"),v,i); - if (addsep) - popup->add_separator(); - } - popup->connect("item_pressed",this,"_add_node"); + String nn = node_names[i]; + String ic = nn.get_slice(":",0); + String v = nn.get_slice(":",1); + bool addsep=false; + if (nn.ends_with(":")) { + addsep=true; + } + popup->add_icon_item(get_icon(ic,"EditorIcons"),v,i); + if (addsep) + popup->add_separator(); + } + popup->connect("item_pressed",this,"_add_node"); - } + } } void ShaderGraphEditor::_bind_methods() { - ObjectTypeDB::bind_method("_add_node",&ShaderGraphEditor::_add_node); - ObjectTypeDB::bind_method("_popup_requested",&ShaderGraphEditor::_popup_requested); + ObjectTypeDB::bind_method("_add_node",&ShaderGraphEditor::_add_node); + ObjectTypeDB::bind_method("_popup_requested",&ShaderGraphEditor::_popup_requested); } const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={ - "GraphInput:Input", // all inputs (shader type dependent) - "GraphScalar:Scalar Constant", //scalar constant - "GraphVector:Vector Constant", //vec3 constant - "GraphRgb:RGB Constant", //rgb constant (shows a color picker instead) - "GraphXform:XForm Constant", // 4x4 matrix constant - "GraphTime:Time:", // time in seconds - "GraphTexscreen:Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader) - "GraphScalarOp:Scalar Operator", // scalar vs scalar op (mul", add", div", etc) - "GraphVecOp:Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc) - "GraphVecScalarOp:Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc) - "GraphRgbOp:RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc. - "GraphXformMult:XForm Multiply", // mat4 x mat4 - "GraphXformVecMult:XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option) - "GraphXformVecImult:Form+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option) - "GraphXformScalarFunc:Scalar Function", // scalar function (sin", cos", etc) - "GraphXformVecFunc:Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc) - "GraphVecLength:Vector Length", // vec3 length - "GraphVecDp:Dot Product:", // vec3 . vec3 (dot product -> scalar output) - "GraphVecToScalars:Vector -> Scalars", // 1 vec3 input", 3 scalar outputs - "GraphScalarsToVec:Scalars -> Vector", // 3 scalar input", 1 vec3 output - "GraphXformToVecs:XForm -> Vectors", // 3 vec input", 1 xform output - "GraphVecsToXform:Vectors -> XForm:", // 3 vec input", 1 xform output - "GraphScalarInterp:Scalar Interpolate", // scalar interpolation (with optional curve) - "GraphVecInterp:Vector Interpolate:", // vec3 interpolation (with optional curve) - "GraphColorRamp:Color Ramp", // vec3 interpolation (with optional curve) - "GraphCurveMap:Curve Remap:", // vec3 interpolation (with optional curve) - "GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material) - "GraphVectorUniform:Vector Uniform", // vec3 uniform (assignable in material) - "GraphRgbUniform:RGB Uniform", // color uniform (assignable in material) - "GraphXformUniform:XForm Uniform", // mat4 uniform (assignable in material) - "GraphTextureUniform:Texture Uniform", // texture input (assignable in material) - "GraphCubeUniform:CubeMap Uniform:", // cubemap input (assignable in material) - "GraphDefaultTexture:CanvasItem Texture:", // cubemap input (assignable in material) - "Output", // output (shader type dependent) - "GraphComment:Comment", // comment + "GraphInput:Input", // all inputs (shader type dependent) + "GraphScalar:Scalar Constant", //scalar constant + "GraphVector:Vector Constant", //vec3 constant + "GraphRgb:RGB Constant", //rgb constant (shows a color picker instead) + "GraphXform:XForm Constant", // 4x4 matrix constant + "GraphTime:Time:", // time in seconds + "GraphTexscreen:Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader) + "GraphScalarOp:Scalar Operator", // scalar vs scalar op (mul", add", div", etc) + "GraphVecOp:Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc) + "GraphVecScalarOp:Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc) + "GraphRgbOp:RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc. + "GraphXformMult:XForm Multiply", // mat4 x mat4 + "GraphXformVecMult:XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option) + "GraphXformVecImult:Form+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option) + "GraphXformScalarFunc:Scalar Function", // scalar function (sin", cos", etc) + "GraphXformVecFunc:Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc) + "GraphVecLength:Vector Length", // vec3 length + "GraphVecDp:Dot Product:", // vec3 . vec3 (dot product -> scalar output) + "GraphVecToScalars:Vector -> Scalars", // 1 vec3 input", 3 scalar outputs + "GraphScalarsToVec:Scalars -> Vector", // 3 scalar input", 1 vec3 output + "GraphXformToVecs:XForm -> Vectors", // 3 vec input", 1 xform output + "GraphVecsToXform:Vectors -> XForm:", // 3 vec input", 1 xform output + "GraphScalarInterp:Scalar Interpolate", // scalar interpolation (with optional curve) + "GraphVecInterp:Vector Interpolate:", // vec3 interpolation (with optional curve) + "GraphColorRamp:Color Ramp", // vec3 interpolation (with optional curve) + "GraphCurveMap:Curve Remap:", // vec3 interpolation (with optional curve) + "GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material) + "GraphVectorUniform:Vector Uniform", // vec3 uniform (assignable in material) + "GraphRgbUniform:RGB Uniform", // color uniform (assignable in material) + "GraphXformUniform:XForm Uniform", // mat4 uniform (assignable in material) + "GraphTextureUniform:Texture Uniform", // texture input (assignable in material) + "GraphCubeUniform:CubeMap Uniform:", // cubemap input (assignable in material) + "GraphDefaultTexture:CanvasItem Texture:", // cubemap input (assignable in material) + "Output", // output (shader type dependent) + "GraphComment:Comment", // comment }; ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { - _2d=p_2d; + _2d=p_2d; - HBoxContainer *hbc = memnew( HBoxContainer ); - popup = memnew( PopupMenu ); - hbc->add_child(popup); - add_child(hbc); + HBoxContainer *hbc = memnew( HBoxContainer ); + popup = memnew( PopupMenu ); + hbc->add_child(popup); + add_child(hbc); - tabs = memnew(TabContainer); - tabs->set_v_size_flags(SIZE_EXPAND_FILL); - add_child(tabs); - const char* sname[ShaderGraph::SHADER_TYPE_MAX]={ - "Vertex", - "Fragment", - "Light" - }; - for(int i=0;iset_v_size_flags(SIZE_EXPAND_FILL); + add_child(tabs); + const char* sname[ShaderGraph::SHADER_TYPE_MAX]={ + "Vertex", + "Fragment", + "Light" + }; + for(int i=0;iget_graph_edit()->set_name(sname[i]); - tabs->add_child(graph_edits[i]->get_graph_edit()); - graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); - graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); - graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); - graph_edits[i]->get_graph_edit()->set_right_disconnects(true); - } + graph_edits[i]= memnew( ShaderGraphView(ShaderGraph::ShaderType(i)) ); + add_child(graph_edits[i]); + graph_edits[i]->get_graph_edit()->set_name(sname[i]); + tabs->add_child(graph_edits[i]->get_graph_edit()); + graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); + graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); + graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); + graph_edits[i]->get_graph_edit()->set_right_disconnects(true); + } - tabs->set_current_tab(1); + tabs->set_current_tab(1); - set_custom_minimum_size(Size2(100,300)); + set_custom_minimum_size(Size2(100,300)); } void ShaderGraphEditorPlugin::edit(Object *p_object) { - shader_editor->edit(p_object->cast_to()); + shader_editor->edit(p_object->cast_to()); } bool ShaderGraphEditorPlugin::handles(Object *p_object) const { - ShaderGraph *shader=p_object->cast_to(); - if (!shader) - return false; - if (_2d) - return shader->get_mode()==Shader::MODE_CANVAS_ITEM; - else - return shader->get_mode()==Shader::MODE_MATERIAL; + ShaderGraph *shader=p_object->cast_to(); + if (!shader) + return false; + if (_2d) + return shader->get_mode()==Shader::MODE_CANVAS_ITEM; + else + return shader->get_mode()==Shader::MODE_MATERIAL; } void ShaderGraphEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { - shader_editor->show(); - } else { + if (p_visible) { + shader_editor->show(); + } else { - shader_editor->hide(); - } + shader_editor->hide(); + } } ShaderGraphEditorPlugin::ShaderGraphEditorPlugin(EditorNode *p_node, bool p_2d) { - _2d=p_2d; - editor=p_node; - shader_editor = memnew( ShaderGraphEditor(p_2d) ); - shader_editor->hide(); - if (p_2d) - CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(shader_editor); - else - SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); + _2d=p_2d; + editor=p_node; + shader_editor = memnew( ShaderGraphEditor(p_2d) ); + shader_editor->hide(); + if (p_2d) + CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(shader_editor); + else + SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); // editor->get_viewport()->add_child(shader_editor); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index c41ec68360..ea21a7706f 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -41,187 +41,189 @@ #include "tools/editor/property_editor.h" #include "scene/resources/shader_graph.h" /** - @author Juan Linietsky + @author Juan Linietsky */ class GraphColorRampEdit : public Control { - OBJ_TYPE(GraphColorRampEdit,Control); + OBJ_TYPE(GraphColorRampEdit,Control); - struct Point { + struct Point { - float offset; - Color color; - bool operator<(const Point& p_ponit) const { - return offset points; + bool grabbing; + int grabbed; + float grabbed_at; + Vector points; - void _color_changed(const Color& p_color); + void _color_changed(const Color& p_color); protected: - void _input_event(const InputEvent& p_event); - void _notification(int p_what); - static void _bind_methods(); + void _input_event(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); public: - void set_ramp(const Vector& p_offsets,const Vector& p_colors); - Vector get_offsets() const; - Vector get_colors() const; - virtual Size2 get_minimum_size() const; - GraphColorRampEdit(); + void set_ramp(const Vector& p_offsets,const Vector& p_colors); + Vector get_offsets() const; + Vector get_colors() const; + virtual Size2 get_minimum_size() const; + GraphColorRampEdit(); }; class GraphCurveMapEdit : public Control { - OBJ_TYPE(GraphCurveMapEdit,Control); + OBJ_TYPE(GraphCurveMapEdit,Control); - struct Point { + struct Point { - float offset; - float height; - bool operator<(const Point& p_ponit) const { - return offset points; + bool grabbing; + int grabbed; + Vector points; - void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); + void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); protected: - void _input_event(const InputEvent& p_event); - void _notification(int p_what); - static void _bind_methods(); + void _input_event(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); public: - void set_points(const Vector& p_points); - Vector get_points() const; - virtual Size2 get_minimum_size() const; - GraphCurveMapEdit(); + void set_points(const Vector& p_points); + Vector get_points() const; + virtual Size2 get_minimum_size() const; + GraphCurveMapEdit(); }; class ShaderGraphView : public Node { - OBJ_TYPE(ShaderGraphView,Node); - - - - CustomPropertyEditor *ped_popup; - bool block_update; - - Label *status; - GraphEdit *graph_edit; - Ref graph; - int edited_id; - - ShaderGraph::ShaderType type; - - void _update_graph(); - void _create_node(int p_id); - - - - void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); - void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); - - void _node_removed(int p_id); - void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); - void _move_node(int p_id,const Vector2& p_to); - - void _scalar_const_changed(double p_value,int p_id); - void _vec_const_changed(double p_value, int p_id, Array p_arr); - void _rgb_const_changed(const Color& p_color, int p_id); - void _xform_const_changed(int p_id,Node* p_button); - void _scalar_op_changed(int p_op, int p_id); - void _vec_op_changed(int p_op, int p_id); - void _vec_scalar_op_changed(int p_op, int p_id); - void _rgb_op_changed(int p_op, int p_id); - void _xform_inv_rev_changed(bool p_enabled, int p_id); - void _scalar_func_changed(int p_func, int p_id); - void _vec_func_changed(int p_func, int p_id); - void _scalar_input_changed(double p_value,int p_id); - void _vec_input_changed(double p_value, int p_id, Array p_arr); - void _xform_input_changed(int p_id,Node* p_button); - void _rgb_input_changed(const Color& p_color, int p_id); - void _tex_input_change(int p_id,Node* p_button); - void _cube_input_change(int p_id); - void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit); - void _tex_edited(int p_id,Node* p_button); - void _cube_edited(int p_id,Node* p_button); - void _variant_edited(); - void _comment_edited(int p_id,Node* p_button); - void _color_ramp_changed(int p_id,Node* p_ramp); - void _curve_changed(int p_id,Node* p_curve); - void _sg_updated(); - Map node_map; + OBJ_TYPE(ShaderGraphView,Node); + + + + CustomPropertyEditor *ped_popup; + bool block_update; + + Label *status; + GraphEdit *graph_edit; + Ref graph; + int edited_id; + + ShaderGraph::ShaderType type; + + void _update_graph(); + void _create_node(int p_id); + + + + void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + + void _node_removed(int p_id); + void _begin_node_move(); + void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); + void _end_node_move(); + void _move_node(int p_id,const Vector2& p_to); + + void _scalar_const_changed(double p_value,int p_id); + void _vec_const_changed(double p_value, int p_id, Array p_arr); + void _rgb_const_changed(const Color& p_color, int p_id); + void _xform_const_changed(int p_id,Node* p_button); + void _scalar_op_changed(int p_op, int p_id); + void _vec_op_changed(int p_op, int p_id); + void _vec_scalar_op_changed(int p_op, int p_id); + void _rgb_op_changed(int p_op, int p_id); + void _xform_inv_rev_changed(bool p_enabled, int p_id); + void _scalar_func_changed(int p_func, int p_id); + void _vec_func_changed(int p_func, int p_id); + void _scalar_input_changed(double p_value,int p_id); + void _vec_input_changed(double p_value, int p_id, Array p_arr); + void _xform_input_changed(int p_id,Node* p_button); + void _rgb_input_changed(const Color& p_color, int p_id); + void _tex_input_change(int p_id,Node* p_button); + void _cube_input_change(int p_id); + void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit); + void _tex_edited(int p_id,Node* p_button); + void _cube_edited(int p_id,Node* p_button); + void _variant_edited(); + void _comment_edited(int p_id,Node* p_button); + void _color_ramp_changed(int p_id,Node* p_ramp); + void _curve_changed(int p_id,Node* p_curve); + void _sg_updated(); + Map node_map; protected: - void _notification(int p_what); - static void _bind_methods(); + void _notification(int p_what); + static void _bind_methods(); public: void add_node(int p_type, const Vector2 &location); - GraphEdit *get_graph_edit() { return graph_edit; } - void set_graph(Ref p_graph); + GraphEdit *get_graph_edit() { return graph_edit; } + void set_graph(Ref p_graph); - ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT); + ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT); }; class ShaderGraphEditor : public VBoxContainer { - OBJ_TYPE(ShaderGraphEditor,VBoxContainer); + OBJ_TYPE(ShaderGraphEditor,VBoxContainer); PopupMenu *popup; - TabContainer *tabs; - ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; - static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; + TabContainer *tabs; + ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; + static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; Vector2 next_location; - bool _2d; - void _add_node(int p_type); + bool _2d; + void _add_node(int p_type); void _popup_requested(const Vector2 &p_position); protected: - void _notification(int p_what); - static void _bind_methods(); + void _notification(int p_what); + static void _bind_methods(); public: - void edit(Ref p_shader); - ShaderGraphEditor(bool p_2d); + void edit(Ref p_shader); + ShaderGraphEditor(bool p_2d); }; class ShaderGraphEditorPlugin : public EditorPlugin { - OBJ_TYPE( ShaderGraphEditorPlugin, EditorPlugin ); + OBJ_TYPE( ShaderGraphEditorPlugin, EditorPlugin ); - bool _2d; - ShaderGraphEditor *shader_editor; - EditorNode *editor; + bool _2d; + ShaderGraphEditor *shader_editor; + EditorNode *editor; public: - virtual String get_name() const { return "ShaderGraph"; } - 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); + virtual String get_name() const { return "ShaderGraph"; } + 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); - ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); - ~ShaderGraphEditorPlugin(); + ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); + ~ShaderGraphEditorPlugin(); }; #endif -- cgit v1.2.3 From f8db8b72155ef904b9399295d3c40737e265e2ad Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Mon, 20 Jul 2015 22:45:22 +0300 Subject: Haiku: update detect.py --- platform/haiku/detect.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 587148838f..d219850bb4 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -17,7 +17,9 @@ def can_build(): return True def get_opts(): - return [] + return [ + ('debug_release', 'Add debug symbols to release version','no') + ] def get_flags(): return [ @@ -41,9 +43,9 @@ def configure(env): if (env["target"]=="release"): if (env["debug_release"]=="yes"): - env.Append(CCFLAGS=['-g2','-fomit-frame-pointer']) + env.Append(CCFLAGS=['-g2']) else: - env.Append(CCFLAGS=['-O2','-ffast-math','-fomit-frame-pointer']) + env.Append(CCFLAGS=['-O3','-ffast-math']) elif (env["target"]=="release_debug"): env.Append(CCFLAGS=['-O2','-ffast-math','-DDEBUG_ENABLED']) elif (env["target"]=="debug"): -- cgit v1.2.3 From 2a43778793ba67c7edb7d96ab30c4c2a8c145c70 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Mon, 20 Jul 2015 22:15:06 -0300 Subject: Fix tab indent --- scene/gui/graph_edit.cpp | 920 ++--- scene/gui/graph_edit.h | 112 +- scene/gui/graph_node.cpp | 660 ++-- scene/gui/graph_node.h | 126 +- scene/resources/default_theme/default_theme.cpp | 90 +- .../editor/plugins/shader_graph_editor_plugin.cpp | 3792 ++++++++++---------- tools/editor/plugins/shader_graph_editor_plugin.h | 254 +- 7 files changed, 2977 insertions(+), 2977 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 4569c71d0b..22a03504c6 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -3,385 +3,385 @@ #include "os/keyboard.h" bool GraphEditFilter::has_point(const Point2& p_point) const { - return ge->_filter_input(p_point); + return ge->_filter_input(p_point); } GraphEditFilter::GraphEditFilter(GraphEdit *p_edit) { - ge=p_edit; + ge=p_edit; } Error GraphEdit::connect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port) { - if (is_node_connected(p_from,p_from_port,p_to,p_to_port)) - return OK; - Connection c; - c.from=p_from; - c.from_port=p_from_port; - c.to=p_to; - c.to_port=p_to_port; - connections.push_back(c); - top_layer->update(); - - return OK; + if (is_node_connected(p_from,p_from_port,p_to,p_to_port)) + return OK; + Connection c; + c.from=p_from; + c.from_port=p_from_port; + c.to=p_to; + c.to_port=p_to_port; + connections.push_back(c); + top_layer->update(); + + return OK; } bool GraphEdit::is_node_connected(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port) { - for(List::Element *E=connections.front();E;E=E->next()) { + for(List::Element *E=connections.front();E;E=E->next()) { - if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) - return true; - } + if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) + return true; + } - return false; + return false; } void GraphEdit::disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port){ - for(List::Element *E=connections.front();E;E=E->next()) { + for(List::Element *E=connections.front();E;E=E->next()) { - if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) { + if (E->get().from==p_from && E->get().from_port==p_from_port && E->get().to==p_to && E->get().to_port==p_to_port) { - connections.erase(E); - top_layer->update(); - return; - } - } + connections.erase(E); + top_layer->update(); + return; + } + } } void GraphEdit::get_connection_list(List *r_connections) const { - *r_connections=connections; + *r_connections=connections; } void GraphEdit::_scroll_moved(double) { - _update_scroll_offset(); - top_layer->update(); + _update_scroll_offset(); + top_layer->update(); } void GraphEdit::_update_scroll_offset() { - for(int i=0;icast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - Point2 pos=gn->get_offset(); - pos-=Point2(h_scroll->get_val(),v_scroll->get_val()); - gn->set_pos(pos); - } + Point2 pos=gn->get_offset(); + pos-=Point2(h_scroll->get_val(),v_scroll->get_val()); + gn->set_pos(pos); + } } void GraphEdit::_update_scroll() { - if (updating) - return; + if (updating) + return; - updating=true; - Rect2 screen; - for(int i=0;icast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - Rect2 r; - r.pos=gn->get_offset(); - r.size=gn->get_size(); - screen = screen.merge(r); - } + Rect2 r; + r.pos=gn->get_offset(); + r.size=gn->get_size(); + screen = screen.merge(r); + } - screen.pos-=get_size(); - screen.size+=get_size()*2.0; + screen.pos-=get_size(); + screen.size+=get_size()*2.0; - h_scroll->set_min(screen.pos.x); - h_scroll->set_max(screen.pos.x+screen.size.x); - h_scroll->set_page(get_size().x); - if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) - h_scroll->hide(); - else - h_scroll->show(); + h_scroll->set_min(screen.pos.x); + h_scroll->set_max(screen.pos.x+screen.size.x); + h_scroll->set_page(get_size().x); + if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page()) + h_scroll->hide(); + else + h_scroll->show(); - v_scroll->set_min(screen.pos.y); - v_scroll->set_max(screen.pos.y+screen.size.y); - v_scroll->set_page(get_size().y); + v_scroll->set_min(screen.pos.y); + v_scroll->set_max(screen.pos.y+screen.size.y); + v_scroll->set_page(get_size().y); - if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) - v_scroll->hide(); - else - v_scroll->show(); + if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page()) + v_scroll->hide(); + else + v_scroll->show(); - _update_scroll_offset(); - updating=false; + _update_scroll_offset(); + updating=false; } void GraphEdit::_graph_node_raised(Node* p_gn) { - GraphNode *gn=p_gn->cast_to(); - ERR_FAIL_COND(!gn); - gn->raise(); - top_layer->raise(); + GraphNode *gn=p_gn->cast_to(); + ERR_FAIL_COND(!gn); + gn->raise(); + top_layer->raise(); } void GraphEdit::_graph_node_moved(Node *p_gn) { - GraphNode *gn=p_gn->cast_to(); - ERR_FAIL_COND(!gn); - top_layer->update(); + GraphNode *gn=p_gn->cast_to(); + ERR_FAIL_COND(!gn); + top_layer->update(); } void GraphEdit::add_child_notify(Node *p_child) { - top_layer->call_deferred("raise"); //top layer always on top! - GraphNode *gn = p_child->cast_to(); - if (gn) { - gn->connect("offset_changed",this,"_graph_node_moved",varray(gn)); - gn->connect("raise_request",this,"_graph_node_raised",varray(gn)); - _graph_node_moved(gn); - gn->set_stop_mouse(false); - } + top_layer->call_deferred("raise"); //top layer always on top! + GraphNode *gn = p_child->cast_to(); + if (gn) { + gn->connect("offset_changed",this,"_graph_node_moved",varray(gn)); + gn->connect("raise_request",this,"_graph_node_raised",varray(gn)); + _graph_node_moved(gn); + gn->set_stop_mouse(false); + } } void GraphEdit::remove_child_notify(Node *p_child) { - top_layer->call_deferred("raise"); //top layer always on top! - GraphNode *gn = p_child->cast_to(); - if (gn) { - gn->disconnect("offset_changed",this,"_graph_node_moved"); - gn->disconnect("raise_request",this,"_graph_node_raised"); - } + top_layer->call_deferred("raise"); //top layer always on top! + GraphNode *gn = p_child->cast_to(); + if (gn) { + gn->disconnect("offset_changed",this,"_graph_node_moved"); + gn->disconnect("raise_request",this,"_graph_node_raised"); + } } void GraphEdit::_notification(int p_what) { - if (p_what==NOTIFICATION_READY) { - Size2 size = top_layer->get_size(); - Size2 hmin = h_scroll->get_combined_minimum_size(); - Size2 vmin = v_scroll->get_combined_minimum_size(); + if (p_what==NOTIFICATION_READY) { + Size2 size = top_layer->get_size(); + Size2 hmin = h_scroll->get_combined_minimum_size(); + Size2 vmin = v_scroll->get_combined_minimum_size(); - v_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,vmin.width); - v_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); - v_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,0); - v_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); + v_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_END,vmin.width); + v_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); + v_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_BEGIN,0); + v_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); - h_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,0); - h_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); - h_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,hmin.height); - h_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); + h_scroll->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,0); + h_scroll->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,0); + h_scroll->set_anchor_and_margin(MARGIN_TOP,ANCHOR_END,hmin.height); + h_scroll->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_END,0); - } - if (p_what==NOTIFICATION_DRAW) { - VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); + } + if (p_what==NOTIFICATION_DRAW) { + VS::get_singleton()->canvas_item_set_clip(get_canvas_item(),true); - } + } - if (p_what==NOTIFICATION_RESIZED) { - _update_scroll(); - top_layer->update(); - } + if (p_what==NOTIFICATION_RESIZED) { + _update_scroll(); + top_layer->update(); + } } bool GraphEdit::_filter_input(const Point2& p_point) { - Ref port =get_icon("port","GraphNode"); + Ref port =get_icon("port","GraphNode"); - float grab_r=port->get_width()*0.5; - for(int i=get_child_count()-1;i>=0;i--) { + float grab_r=port->get_width()*0.5; + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - for(int j=0;jget_connection_output_count();j++) { + for(int j=0;jget_connection_output_count();j++) { - Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); - if (pos.distance_to(p_point)get_connection_output_pos(j)+gn->get_pos(); + if (pos.distance_to(p_point)get_connection_input_count();j++) { + for(int j=0;jget_connection_input_count();j++) { - Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); - if (pos.distance_to(p_point)get_connection_input_pos(j)+gn->get_pos(); + if (pos.distance_to(p_point) port =get_icon("port","GraphNode"); - Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); - float grab_r=port->get_width()*0.5; - for(int i=get_child_count()-1;i>=0;i--) { + Ref port =get_icon("port","GraphNode"); + Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); + float grab_r=port->get_width()*0.5; + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - for(int j=0;jget_connection_output_count();j++) { + for(int j=0;jget_connection_output_count();j++) { - Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); - if (pos.distance_to(mpos)get_connection_output_pos(j)+gn->get_pos(); + if (pos.distance_to(mpos)get_name(); - connecting_index=j; - connecting_out=true; - connecting_type=gn->get_connection_output_type(j); - connecting_color=gn->get_connection_output_color(j); - connecting_target=false; - connecting_to=pos; - return; - } + connecting=true; + connecting_from=gn->get_name(); + connecting_index=j; + connecting_out=true; + connecting_type=gn->get_connection_output_type(j); + connecting_color=gn->get_connection_output_color(j); + connecting_target=false; + connecting_to=pos; + return; + } - } + } - for(int j=0;jget_connection_input_count();j++) { + for(int j=0;jget_connection_input_count();j++) { - Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); + Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); - if (pos.distance_to(mpos)::Element*E=connections.front();E;E=E->next()) { + if (right_disconnects) { + //check disconnect + for (List::Element*E=connections.front();E;E=E->next()) { - if (E->get().to==gn->get_name() && E->get().to_port==j) { + if (E->get().to==gn->get_name() && E->get().to_port==j) { - Node*fr = get_node(String(E->get().from)); - if (fr && fr->cast_to()) { + Node*fr = get_node(String(E->get().from)); + if (fr && fr->cast_to()) { - connecting_from=E->get().from; - connecting_index=E->get().from_port; - connecting_out=true; - connecting_type=fr->cast_to()->get_connection_output_type(E->get().from_port); - connecting_color=fr->cast_to()->get_connection_output_color(E->get().from_port); - connecting_target=false; - connecting_to=pos; + connecting_from=E->get().from; + connecting_index=E->get().from_port; + connecting_out=true; + connecting_type=fr->cast_to()->get_connection_output_type(E->get().from_port); + connecting_color=fr->cast_to()->get_connection_output_color(E->get().from_port); + connecting_target=false; + connecting_to=pos; - emit_signal("disconnection_request",E->get().from,E->get().from_port,E->get().to,E->get().to_port); - fr = get_node(String(connecting_from)); //maybe it was erased - if (fr && fr->cast_to()) { - connecting=true; - } - return; - } + emit_signal("disconnection_request",E->get().from,E->get().from_port,E->get().to,E->get().to_port); + fr = get_node(String(connecting_from)); //maybe it was erased + if (fr && fr->cast_to()) { + connecting=true; + } + return; + } - } - } - } + } + } + } - connecting=true; - connecting_from=gn->get_name(); - connecting_index=j; - connecting_out=false; - connecting_type=gn->get_connection_input_type(j); - connecting_color=gn->get_connection_input_color(j); - connecting_target=false; - connecting_to=pos; - return; - } + connecting=true; + connecting_from=gn->get_name(); + connecting_index=j; + connecting_out=false; + connecting_type=gn->get_connection_input_type(j); + connecting_color=gn->get_connection_input_color(j); + connecting_target=false; + connecting_to=pos; + return; + } - } - } - } + } + } + } - if (p_ev.type==InputEvent::MOUSE_MOTION && connecting) { + if (p_ev.type==InputEvent::MOUSE_MOTION && connecting) { - connecting_to=Vector2(p_ev.mouse_motion.x,p_ev.mouse_motion.y); - connecting_target=false; - top_layer->update(); + connecting_to=Vector2(p_ev.mouse_motion.x,p_ev.mouse_motion.y); + connecting_target=false; + top_layer->update(); - Ref port =get_icon("port","GraphNode"); - Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); - float grab_r=port->get_width()*0.5; - for(int i=get_child_count()-1;i>=0;i--) { + Ref port =get_icon("port","GraphNode"); + Vector2 mpos(p_ev.mouse_button.x,p_ev.mouse_button.y); + float grab_r=port->get_width()*0.5; + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - if (!connecting_out) { - for(int j=0;jget_connection_output_count();j++) { + if (!connecting_out) { + for(int j=0;jget_connection_output_count();j++) { - Vector2 pos = gn->get_connection_output_pos(j)+gn->get_pos(); - int type =gn->get_connection_output_type(j); - if (type==connecting_type && pos.distance_to(mpos)get_connection_output_pos(j)+gn->get_pos(); + int type =gn->get_connection_output_type(j); + if (type==connecting_type && pos.distance_to(mpos)get_name(); - connecting_target_index=j; - return; - } + connecting_target=true; + connecting_to=pos; + connecting_target_to=gn->get_name(); + connecting_target_index=j; + return; + } - } - } else { + } + } else { - for(int j=0;jget_connection_input_count();j++) { + for(int j=0;jget_connection_input_count();j++) { - Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); - int type =gn->get_connection_input_type(j); - if (type==connecting_type && pos.distance_to(mpos)get_name(); - connecting_target_index=j; - return; - } - } - } - } - } + Vector2 pos = gn->get_connection_input_pos(j)+gn->get_pos(); + int type =gn->get_connection_input_type(j); + if (type==connecting_type && pos.distance_to(mpos)get_name(); + connecting_target_index=j; + return; + } + } + } + } + } - if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index==BUTTON_LEFT && !p_ev.mouse_button.pressed) { + if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index==BUTTON_LEFT && !p_ev.mouse_button.pressed) { - if (connecting && connecting_target) { + if (connecting && connecting_target) { - String from = connecting_from; - int from_slot = connecting_index; - String to =connecting_target_to; - int to_slot = connecting_target_index; + String from = connecting_from; + int from_slot = connecting_index; + String to =connecting_target_to; + int to_slot = connecting_target_index; - if (!connecting_out) { - SWAP(from,to); - SWAP(from_slot,to_slot); - } - emit_signal("connection_request",from,from_slot,to,to_slot); - - } - connecting=false; - top_layer->update(); + if (!connecting_out) { + SWAP(from,to); + SWAP(from_slot,to_slot); + } + emit_signal("connection_request",from,from_slot,to,to_slot); + + } + connecting=false; + top_layer->update(); - } + } @@ -389,295 +389,295 @@ void GraphEdit::_top_layer_input(const InputEvent& p_ev) { void GraphEdit::_draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color) { - static const int steps = 20; + static const int steps = 20; - Rect2 r; - r.pos=p_from; - r.expand_to(p_to); - Vector2 sign=Vector2((p_from.x < p_to.x) ? 1 : -1,(p_from.y < p_to.y) ? 1 : -1); - bool flip = sign.x * sign.y < 0; + Rect2 r; + r.pos=p_from; + r.expand_to(p_to); + Vector2 sign=Vector2((p_from.x < p_to.x) ? 1 : -1,(p_from.y < p_to.y) ? 1 : -1); + bool flip = sign.x * sign.y < 0; - Vector2 prev; - for(int i=0;i<=steps;i++) { + Vector2 prev; + for(int i=0;i<=steps;i++) { - float d = i/float(steps); - float c=-Math::cos(d*Math_PI) * 0.5+0.5; - if (flip) - c=1.0-c; - Vector2 p = r.pos+Vector2(d*r.size.width,c*r.size.height); + float d = i/float(steps); + float c=-Math::cos(d*Math_PI) * 0.5+0.5; + if (flip) + c=1.0-c; + Vector2 p = r.pos+Vector2(d*r.size.width,c*r.size.height); - if (i>0) { + if (i>0) { - top_layer->draw_line(prev,p,p_color,2); - } + top_layer->draw_line(prev,p,p_color,2); + } - prev=p; - } + prev=p; + } } void GraphEdit::_top_layer_draw() { - _update_scroll(); - - if (connecting) { - - Node *fromn = get_node(connecting_from); - ERR_FAIL_COND(!fromn); - GraphNode *from = fromn->cast_to(); - ERR_FAIL_COND(!from); - Vector2 pos; - if (connecting_out) - pos=from->get_connection_output_pos(connecting_index); - else - pos=from->get_connection_input_pos(connecting_index); - pos+=from->get_pos(); - - Vector2 topos; - topos=connecting_to; - - Color col=connecting_color; - - if (connecting_target) { - col.r+=0.4; - col.g+=0.4; - col.b+=0.4; - } - _draw_cos_line(pos,topos,col); - } - - List::Element* > to_erase; - for(List::Element *E=connections.front();E;E=E->next()) { - - NodePath fromnp(E->get().from); - - Node * from = get_node(fromnp); - if (!from) { - to_erase.push_back(E); - continue; - } - - GraphNode *gfrom = from->cast_to(); - - if (!gfrom) { - to_erase.push_back(E); - continue; - } - - NodePath tonp(E->get().to); - Node * to = get_node(tonp); - if (!to) { - to_erase.push_back(E); - continue; - } - - GraphNode *gto = to->cast_to(); - - if (!gto) { - to_erase.push_back(E); - continue; - } - - Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos(); - Color color = gfrom->get_connection_output_color(E->get().from_port); - Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos(); - _draw_cos_line(frompos,topos,color); - - } - - while(to_erase.size()) { - connections.erase(to_erase.front()->get()); - to_erase.pop_front(); - } - //draw connections + _update_scroll(); + + if (connecting) { + + Node *fromn = get_node(connecting_from); + ERR_FAIL_COND(!fromn); + GraphNode *from = fromn->cast_to(); + ERR_FAIL_COND(!from); + Vector2 pos; + if (connecting_out) + pos=from->get_connection_output_pos(connecting_index); + else + pos=from->get_connection_input_pos(connecting_index); + pos+=from->get_pos(); + + Vector2 topos; + topos=connecting_to; + + Color col=connecting_color; + + if (connecting_target) { + col.r+=0.4; + col.g+=0.4; + col.b+=0.4; + } + _draw_cos_line(pos,topos,col); + } + + List::Element* > to_erase; + for(List::Element *E=connections.front();E;E=E->next()) { + + NodePath fromnp(E->get().from); + + Node * from = get_node(fromnp); + if (!from) { + to_erase.push_back(E); + continue; + } + + GraphNode *gfrom = from->cast_to(); + + if (!gfrom) { + to_erase.push_back(E); + continue; + } + + NodePath tonp(E->get().to); + Node * to = get_node(tonp); + if (!to) { + to_erase.push_back(E); + continue; + } + + GraphNode *gto = to->cast_to(); + + if (!gto) { + to_erase.push_back(E); + continue; + } + + Vector2 frompos=gfrom->get_connection_output_pos(E->get().from_port)+gfrom->get_pos(); + Color color = gfrom->get_connection_output_color(E->get().from_port); + Vector2 topos=gto->get_connection_input_pos(E->get().to_port)+gto->get_pos(); + _draw_cos_line(frompos,topos,color); + + } + + while(to_erase.size()) { + connections.erase(to_erase.front()->get()); + to_erase.pop_front(); + } + //draw connections } void GraphEdit::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { - h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); - v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); - } + if (p_ev.type==InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask&BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask&BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) { + h_scroll->set_val( h_scroll->get_val() - p_ev.mouse_motion.relative_x ); + v_scroll->set_val( v_scroll->get_val() - p_ev.mouse_motion.relative_y ); + } - if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { + if (p_ev.type==InputEvent::MOUSE_MOTION && dragging) { - just_selected=true; - drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); - for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (gn && gn->is_selected()) - gn->set_offset(gn->get_drag_from()+drag_accum); - } - } + just_selected=true; + drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y); + for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn=get_child(i)->cast_to(); + if (gn && gn->is_selected()) + gn->set_offset(gn->get_drag_from()+drag_accum); + } + } - if (p_ev.type== InputEvent::MOUSE_BUTTON) { + if (p_ev.type== InputEvent::MOUSE_BUTTON) { - const InputEventMouseButton &b=p_ev.mouse_button; + const InputEventMouseButton &b=p_ev.mouse_button; - if (b.button_index==BUTTON_RIGHT && b.pressed) - { - emit_signal("popup_request", Vector2(b.global_x, b.global_y)); - } + if (b.button_index==BUTTON_RIGHT && b.pressed) + { + emit_signal("popup_request", Vector2(b.global_x, b.global_y)); + } - if (b.button_index==BUTTON_LEFT && !b.pressed && dragging) { - if (!just_selected && drag_accum==Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { - //deselect current node - for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); + if (b.button_index==BUTTON_LEFT && !b.pressed && dragging) { + if (!just_selected && drag_accum==Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + //deselect current node + for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn=get_child(i)->cast_to(); - if (gn && gn->get_rect().has_point(get_local_mouse_pos())) - gn->set_selected(false); - } - } + if (gn && gn->get_rect().has_point(get_local_mouse_pos())) + gn->set_selected(false); + } + } - if (drag_accum!=Vector2()) { + if (drag_accum!=Vector2()) { - emit_signal("_begin_node_move"); + emit_signal("_begin_node_move"); - for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (gn && gn->is_selected()) - gn->set_drag(false); - } + for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn=get_child(i)->cast_to(); + if (gn && gn->is_selected()) + gn->set_drag(false); + } - emit_signal("_end_node_move"); - } + emit_signal("_end_node_move"); + } - dragging = false; + dragging = false; - top_layer->update(); - } + top_layer->update(); + } - if (b.button_index==BUTTON_LEFT && b.pressed) { + if (b.button_index==BUTTON_LEFT && b.pressed) { - GraphNode *gn; - for(int i=get_child_count()-1;i>=0;i--) { + GraphNode *gn; + for(int i=get_child_count()-1;i>=0;i--) { - gn=get_child(i)->cast_to(); + gn=get_child(i)->cast_to(); - if (gn && gn->get_rect().has_point(get_local_mouse_pos())) - break; - } + if (gn && gn->get_rect().has_point(get_local_mouse_pos())) + break; + } - if (gn) { + if (gn) { - if (_filter_input(Vector2(b.x,b.y))) - return; + if (_filter_input(Vector2(b.x,b.y))) + return; - dragging = true; - drag_accum = Vector2(); - just_selected = !gn->is_selected(); - if(!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { - for (int i = 0; i < get_child_count(); i++) { - GraphNode *o_gn = get_child(i)->cast_to(); - if (o_gn) - o_gn->set_selected(o_gn == gn); - } - } + dragging = true; + drag_accum = Vector2(); + just_selected = !gn->is_selected(); + if(!gn->is_selected() && !Input::get_singleton()->is_key_pressed(KEY_CONTROL)) { + for (int i = 0; i < get_child_count(); i++) { + GraphNode *o_gn = get_child(i)->cast_to(); + if (o_gn) + o_gn->set_selected(o_gn == gn); + } + } - gn->set_selected(true); - for (int i = 0; i < get_child_count(); i++) { - GraphNode *o_gn = get_child(i)->cast_to(); - if (!o_gn) - continue; - if (o_gn->is_selected()) - o_gn->set_drag(true); - } + gn->set_selected(true); + for (int i = 0; i < get_child_count(); i++) { + GraphNode *o_gn = get_child(i)->cast_to(); + if (!o_gn) + continue; + if (o_gn->is_selected()) + o_gn->set_drag(true); + } - } else { - for(int i=get_child_count()-1;i>=0;i--) { + } else { + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; - gn->set_selected(false); - } - } - } - } + gn->set_selected(false); + } + } + } + } } void GraphEdit::clear_connections() { - connections.clear(); - update(); + connections.clear(); + update(); } void GraphEdit::set_right_disconnects(bool p_enable) { - right_disconnects=p_enable; + right_disconnects=p_enable; } bool GraphEdit::is_right_disconnects_enabled() const{ - return right_disconnects; + return right_disconnects; } Array GraphEdit::_get_connection_list() const { - List conns; - get_connection_list(&conns); - Array arr; - for(List::Element *E=conns.front();E;E=E->next()) { - Dictionary d; - d["from"]=E->get().from; - d["from_port"]=E->get().from_port; - d["to"]=E->get().to; - d["to_port"]=E->get().to_port; - arr.push_back(d); - } - return arr; + List conns; + get_connection_list(&conns); + Array arr; + for(List::Element *E=conns.front();E;E=E->next()) { + Dictionary d; + d["from"]=E->get().from; + d["from_port"]=E->get().from_port; + d["to"]=E->get().to; + d["to_port"]=E->get().to_port; + arr.push_back(d); + } + return arr; } void GraphEdit::_bind_methods() { - ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node); - ObjectTypeDB::bind_method(_MD("is_node_connected","from","from_port","to","to_port"),&GraphEdit::is_node_connected); - ObjectTypeDB::bind_method(_MD("disconnect_node","from","from_port","to","to_port"),&GraphEdit::disconnect_node); - ObjectTypeDB::bind_method(_MD("get_connection_list"),&GraphEdit::_get_connection_list); + ObjectTypeDB::bind_method(_MD("connect_node:Error","from","from_port","to","to_port"),&GraphEdit::connect_node); + ObjectTypeDB::bind_method(_MD("is_node_connected","from","from_port","to","to_port"),&GraphEdit::is_node_connected); + ObjectTypeDB::bind_method(_MD("disconnect_node","from","from_port","to","to_port"),&GraphEdit::disconnect_node); + ObjectTypeDB::bind_method(_MD("get_connection_list"),&GraphEdit::_get_connection_list); - ObjectTypeDB::bind_method(_MD("set_right_disconnects","enable"),&GraphEdit::set_right_disconnects); - ObjectTypeDB::bind_method(_MD("is_right_disconnects_enabled"),&GraphEdit::is_right_disconnects_enabled); + ObjectTypeDB::bind_method(_MD("set_right_disconnects","enable"),&GraphEdit::set_right_disconnects); + ObjectTypeDB::bind_method(_MD("is_right_disconnects_enabled"),&GraphEdit::is_right_disconnects_enabled); - ObjectTypeDB::bind_method(_MD("_graph_node_moved"),&GraphEdit::_graph_node_moved); - ObjectTypeDB::bind_method(_MD("_graph_node_raised"),&GraphEdit::_graph_node_raised); + ObjectTypeDB::bind_method(_MD("_graph_node_moved"),&GraphEdit::_graph_node_moved); + ObjectTypeDB::bind_method(_MD("_graph_node_raised"),&GraphEdit::_graph_node_raised); - ObjectTypeDB::bind_method(_MD("_top_layer_input"),&GraphEdit::_top_layer_input); - ObjectTypeDB::bind_method(_MD("_top_layer_draw"),&GraphEdit::_top_layer_draw); - ObjectTypeDB::bind_method(_MD("_scroll_moved"),&GraphEdit::_scroll_moved); + ObjectTypeDB::bind_method(_MD("_top_layer_input"),&GraphEdit::_top_layer_input); + ObjectTypeDB::bind_method(_MD("_top_layer_draw"),&GraphEdit::_top_layer_draw); + ObjectTypeDB::bind_method(_MD("_scroll_moved"),&GraphEdit::_scroll_moved); - ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event); + ObjectTypeDB::bind_method(_MD("_input_event"),&GraphEdit::_input_event); - ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); - ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); - ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); - ADD_SIGNAL(MethodInfo("_begin_node_move")); - ADD_SIGNAL(MethodInfo("_end_node_move")); + ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); + ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); + ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); + ADD_SIGNAL(MethodInfo("_begin_node_move")); + ADD_SIGNAL(MethodInfo("_end_node_move")); } GraphEdit::GraphEdit() { - top_layer=NULL; - top_layer=memnew(GraphEditFilter(this)); - add_child(top_layer); - top_layer->set_stop_mouse(false); - top_layer->set_area_as_parent_rect(); - top_layer->connect("draw",this,"_top_layer_draw"); + top_layer=NULL; + top_layer=memnew(GraphEditFilter(this)); + add_child(top_layer); top_layer->set_stop_mouse(false); - top_layer->connect("input_event",this,"_top_layer_input"); + top_layer->set_area_as_parent_rect(); + top_layer->connect("draw",this,"_top_layer_draw"); + top_layer->set_stop_mouse(false); + top_layer->connect("input_event",this,"_top_layer_input"); - h_scroll = memnew(HScrollBar); - h_scroll->set_name("_h_scroll"); - top_layer->add_child(h_scroll); + h_scroll = memnew(HScrollBar); + h_scroll->set_name("_h_scroll"); + top_layer->add_child(h_scroll); - v_scroll = memnew(VScrollBar); - v_scroll->set_name("_v_scroll"); - top_layer->add_child(v_scroll); - updating=false; - connecting=false; - right_disconnects=false; + v_scroll = memnew(VScrollBar); + v_scroll->set_name("_v_scroll"); + top_layer->add_child(v_scroll); + updating=false; + connecting=false; + right_disconnects=false; - h_scroll->connect("value_changed", this,"_scroll_moved"); - v_scroll->connect("value_changed", this,"_scroll_moved"); + h_scroll->connect("value_changed", this,"_scroll_moved"); + v_scroll->connect("value_changed", this,"_scroll_moved"); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 2f9a5fc954..5ab0f3300e 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -8,95 +8,95 @@ class GraphEdit; class GraphEditFilter : public Control { - OBJ_TYPE(GraphEditFilter,Control); + OBJ_TYPE(GraphEditFilter,Control); -friend class GraphEdit; - GraphEdit *ge; - virtual bool has_point(const Point2& p_point) const; + friend class GraphEdit; + GraphEdit *ge; + virtual bool has_point(const Point2& p_point) const; public: - GraphEditFilter(GraphEdit *p_edit); + GraphEditFilter(GraphEdit *p_edit); }; class GraphEdit : public Control { - OBJ_TYPE(GraphEdit,Control); + OBJ_TYPE(GraphEdit,Control); public: - struct Connection { - StringName from; - StringName to; - int from_port; - int to_port; + struct Connection { + StringName from; + StringName to; + int from_port; + int to_port; - }; + }; private: - HScrollBar* h_scroll; - VScrollBar* v_scroll; + HScrollBar* h_scroll; + VScrollBar* v_scroll; - bool connecting; - String connecting_from; - bool connecting_out; - int connecting_index; - int connecting_type; - Color connecting_color; - bool connecting_target; - Vector2 connecting_to; - String connecting_target_to; - int connecting_target_index; + bool connecting; + String connecting_from; + bool connecting_out; + int connecting_index; + int connecting_type; + Color connecting_color; + bool connecting_target; + Vector2 connecting_to; + String connecting_target_to; + int connecting_target_index; - bool dragging; - bool just_selected; - Vector2 drag_accum; + bool dragging; + bool just_selected; + Vector2 drag_accum; - bool right_disconnects; - bool updating; - List connections; + bool right_disconnects; + bool updating; + List connections; - void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); + void _draw_cos_line(const Vector2& p_from, const Vector2& p_to,const Color& p_color); - void _graph_node_raised(Node* p_gn); - void _graph_node_moved(Node *p_gn); + void _graph_node_raised(Node* p_gn); + void _graph_node_moved(Node *p_gn); - void _update_scroll(); - void _scroll_moved(double); - void _input_event(const InputEvent& p_ev); + void _update_scroll(); + void _scroll_moved(double); + void _input_event(const InputEvent& p_ev); - GraphEditFilter *top_layer; - void _top_layer_input(const InputEvent& p_ev); - void _top_layer_draw(); - void _update_scroll_offset(); + GraphEditFilter *top_layer; + void _top_layer_input(const InputEvent& p_ev); + void _top_layer_draw(); + void _update_scroll_offset(); - Array _get_connection_list() const; + Array _get_connection_list() const; -friend class GraphEditFilter; - bool _filter_input(const Point2& p_point); + friend class GraphEditFilter; + bool _filter_input(const Point2& p_point); protected: - static void _bind_methods(); - virtual void add_child_notify(Node *p_child); - virtual void remove_child_notify(Node *p_child); - void _notification(int p_what); + static void _bind_methods(); + virtual void add_child_notify(Node *p_child); + virtual void remove_child_notify(Node *p_child); + void _notification(int p_what); public: - Error connect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); - bool is_node_connected(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); - void disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); - void clear_connections(); + Error connect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); + bool is_node_connected(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); + void disconnect_node(const StringName& p_from, int p_from_port,const StringName& p_to,int p_to_port); + void clear_connections(); - GraphEditFilter *get_top_layer() const { return top_layer; } - void get_connection_list(List *r_connections) const; + GraphEditFilter *get_top_layer() const { return top_layer; } + void get_connection_list(List *r_connections) const; - void set_right_disconnects(bool p_enable); - bool is_right_disconnects_enabled() const; + void set_right_disconnects(bool p_enable); + bool is_right_disconnects_enabled() const; - GraphEdit(); + GraphEdit(); }; #endif // GRAPHEdit_H diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 760eb6ceed..f0917aa4d1 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -4,91 +4,91 @@ bool GraphNode::_set(const StringName& p_name, const Variant& p_value) { - if (!p_name.operator String().begins_with("slot/")) - return false; + if (!p_name.operator String().begins_with("slot/")) + return false; - int idx=p_name.operator String().get_slice("/",1).to_int(); - String what = p_name.operator String().get_slice("/",2); + int idx=p_name.operator String().get_slice("/",1).to_int(); + String what = p_name.operator String().get_slice("/",2); - Slot si; - if (slot_info.has(idx)) - si=slot_info[idx]; + Slot si; + if (slot_info.has(idx)) + si=slot_info[idx]; - if (what=="left_enabled") - si.enable_left=p_value; - else if (what=="left_type") - si.type_left=p_value; - else if (what=="left_color") - si.color_left=p_value; - else if (what=="right_enabled") - si.enable_right=p_value; - else if (what=="right_type") - si.type_right=p_value; - else if (what=="right_color") - si.color_right=p_value; - else - return false; + if (what=="left_enabled") + si.enable_left=p_value; + else if (what=="left_type") + si.type_left=p_value; + else if (what=="left_color") + si.color_left=p_value; + else if (what=="right_enabled") + si.enable_right=p_value; + else if (what=="right_type") + si.type_right=p_value; + else if (what=="right_color") + si.color_right=p_value; + else + return false; - set_slot(idx,si.enable_left,si.type_left,si.color_left,si.enable_right,si.type_right,si.color_right); - update(); - return true; + set_slot(idx,si.enable_left,si.type_left,si.color_left,si.enable_right,si.type_right,si.color_right); + update(); + return true; } bool GraphNode::_get(const StringName& p_name,Variant &r_ret) const{ - if (!p_name.operator String().begins_with("slot/")) { - return false; - } + if (!p_name.operator String().begins_with("slot/")) { + return false; + } - int idx=p_name.operator String().get_slice("/",1).to_int(); - String what = p_name.operator String().get_slice("/",2); + int idx=p_name.operator String().get_slice("/",1).to_int(); + String what = p_name.operator String().get_slice("/",2); - Slot si; - if (slot_info.has(idx)) - si=slot_info[idx]; + Slot si; + if (slot_info.has(idx)) + si=slot_info[idx]; - if (what=="left_enabled") - r_ret=si.enable_left; - else if (what=="left_type") - r_ret=si.type_left; - else if (what=="left_color") - r_ret=si.color_left; - else if (what=="right_enabled") - r_ret=si.enable_right; - else if (what=="right_type") - r_ret=si.type_right; - else if (what=="right_color") - r_ret=si.color_right; - else - return false; + if (what=="left_enabled") + r_ret=si.enable_left; + else if (what=="left_type") + r_ret=si.type_left; + else if (what=="left_color") + r_ret=si.color_left; + else if (what=="right_enabled") + r_ret=si.enable_right; + else if (what=="right_type") + r_ret=si.type_right; + else if (what=="right_color") + r_ret=si.color_right; + else + return false; - return true; + return true; } void GraphNode::_get_property_list( List *p_list) const{ - int idx=0; - for(int i=0;icast_to(); - if (!c || c->is_set_as_toplevel() ) - continue; + int idx=0; + for(int i=0;icast_to(); + if (!c || c->is_set_as_toplevel() ) + continue; - String base="slot/"+itos(idx)+"/"; + String base="slot/"+itos(idx)+"/"; - p_list->push_back(PropertyInfo(Variant::BOOL,base+"left_enabled")); - p_list->push_back(PropertyInfo(Variant::INT,base+"left_type")); - p_list->push_back(PropertyInfo(Variant::COLOR,base+"left_color")); - p_list->push_back(PropertyInfo(Variant::BOOL,base+"right_enabled")); - p_list->push_back(PropertyInfo(Variant::INT,base+"right_type")); - p_list->push_back(PropertyInfo(Variant::COLOR,base+"right_color")); + p_list->push_back(PropertyInfo(Variant::BOOL,base+"left_enabled")); + p_list->push_back(PropertyInfo(Variant::INT,base+"left_type")); + p_list->push_back(PropertyInfo(Variant::COLOR,base+"left_color")); + p_list->push_back(PropertyInfo(Variant::BOOL,base+"right_enabled")); + p_list->push_back(PropertyInfo(Variant::INT,base+"right_type")); + p_list->push_back(PropertyInfo(Variant::COLOR,base+"right_color")); - idx++; - } + idx++; + } } @@ -96,61 +96,61 @@ void GraphNode::_resort() { - int sep=get_constant("separation"); - Ref sb=get_stylebox("frame"); - bool first=true; + int sep=get_constant("separation"); + Ref sb=get_stylebox("frame"); + bool first=true; - Size2 minsize; + Size2 minsize; - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + for(int i=0;icast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - minsize.y+=size.y; - minsize.x=MAX(minsize.x,size.x); + minsize.y+=size.y; + minsize.x=MAX(minsize.x,size.x); - if (first) - first=false; - else - minsize.y+=sep; + if (first) + first=false; + else + minsize.y+=sep; - } + } - int vofs=0; - int w = get_size().x - sb->get_minimum_size().x; + int vofs=0; + int w = get_size().x - sb->get_minimum_size().x; - cache_y.clear(); - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + cache_y.clear(); + for(int i=0;icast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - Rect2 r(sb->get_margin(MARGIN_LEFT),sb->get_margin(MARGIN_TOP)+vofs,w,size.y); + Rect2 r(sb->get_margin(MARGIN_LEFT),sb->get_margin(MARGIN_TOP)+vofs,w,size.y); - fit_child_in_rect(c,r); - cache_y.push_back(vofs+size.y*0.5); + fit_child_in_rect(c,r); + cache_y.push_back(vofs+size.y*0.5); - if (vofs>0) - vofs+=sep; - vofs+=size.y; + if (vofs>0) + vofs+=sep; + vofs+=size.y; - } + } - _change_notify(); - update(); - connpos_dirty=true; + _change_notify(); + update(); + connpos_dirty=true; } @@ -158,124 +158,124 @@ void GraphNode::_resort() { void GraphNode::_notification(int p_what) { - if (p_what==NOTIFICATION_DRAW) { + if (p_what==NOTIFICATION_DRAW) { - Ref sb=get_stylebox(selected ? "selectedframe" : "frame"); - Ref port =get_icon("port"); - Ref close =get_icon("close"); - int close_offset = get_constant("close_offset"); - Ref title_font = get_font("title_font"); - int title_offset = get_constant("title_offset"); - Color title_color = get_color("title_color"); - Point2i icofs = -port->get_size()*0.5; - int edgeofs=get_constant("port_offset"); - icofs.y+=sb->get_margin(MARGIN_TOP); - draw_style_box(sb,Rect2(Point2(),get_size())); + Ref sb=get_stylebox(selected ? "selectedframe" : "frame"); + Ref port =get_icon("port"); + Ref close =get_icon("close"); + int close_offset = get_constant("close_offset"); + Ref title_font = get_font("title_font"); + int title_offset = get_constant("title_offset"); + Color title_color = get_color("title_color"); + Point2i icofs = -port->get_size()*0.5; + int edgeofs=get_constant("port_offset"); + icofs.y+=sb->get_margin(MARGIN_TOP); + draw_style_box(sb,Rect2(Point2(),get_size())); - int w = get_size().width-sb->get_minimum_size().x; + int w = get_size().width-sb->get_minimum_size().x; - if (show_close) - w-=close->get_width(); + if (show_close) + w-=close->get_width(); - draw_string(title_font,Point2(sb->get_margin(MARGIN_LEFT),-title_font->get_height()+title_font->get_ascent()+title_offset),title,title_color,w); - if (show_close) { - Vector2 cpos = Point2(w+sb->get_margin(MARGIN_LEFT),-close->get_height()+close_offset); - draw_texture(close,cpos); - close_rect.pos=cpos; - close_rect.size=close->get_size(); - } else { - close_rect=Rect2(); - } + draw_string(title_font,Point2(sb->get_margin(MARGIN_LEFT),-title_font->get_height()+title_font->get_ascent()+title_offset),title,title_color,w); + if (show_close) { + Vector2 cpos = Point2(w+sb->get_margin(MARGIN_LEFT),-close->get_height()+close_offset); + draw_texture(close,cpos); + close_rect.pos=cpos; + close_rect.size=close->get_size(); + } else { + close_rect=Rect2(); + } - for (Map::Element *E=slot_info.front();E;E=E->next()) { + for (Map::Element *E=slot_info.front();E;E=E->next()) { - if (E->key() < 0 || E->key()>=cache_y.size()) - continue; - if (!slot_info.has(E->key())) - continue; - const Slot &s=slot_info[E->key()]; - //left - if (s.enable_left) - port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); - if (s.enable_right) - port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); + if (E->key() < 0 || E->key()>=cache_y.size()) + continue; + if (!slot_info.has(E->key())) + continue; + const Slot &s=slot_info[E->key()]; + //left + if (s.enable_left) + port->draw(get_canvas_item(),icofs+Point2(edgeofs,cache_y[E->key()]),s.color_left); + if (s.enable_right) + port->draw(get_canvas_item(),icofs+Point2(get_size().x-edgeofs,cache_y[E->key()]),s.color_right); - } - } + } + } - if (p_what==NOTIFICATION_SORT_CHILDREN) { + if (p_what==NOTIFICATION_SORT_CHILDREN) { - _resort(); - } + _resort(); + } } void GraphNode::set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right) { - ERR_FAIL_COND(p_idx<0); + ERR_FAIL_COND(p_idx<0); - if (!p_enable_left && p_type_left==0 && p_color_left==Color(1,1,1,1) && !p_enable_right && p_type_right==0 && p_color_right==Color(1,1,1,1)) { - slot_info.erase(p_idx); - return; - } + if (!p_enable_left && p_type_left==0 && p_color_left==Color(1,1,1,1) && !p_enable_right && p_type_right==0 && p_color_right==Color(1,1,1,1)) { + slot_info.erase(p_idx); + return; + } - Slot s; - s.enable_left=p_enable_left; - s.type_left=p_type_left; - s.color_left=p_color_left; - s.enable_right=p_enable_right; - s.type_right=p_type_right; - s.color_right=p_color_right; - slot_info[p_idx]=s; - update(); - connpos_dirty=true; + Slot s; + s.enable_left=p_enable_left; + s.type_left=p_type_left; + s.color_left=p_color_left; + s.enable_right=p_enable_right; + s.type_right=p_type_right; + s.color_right=p_color_right; + slot_info[p_idx]=s; + update(); + connpos_dirty=true; } void GraphNode::clear_slot(int p_idx){ - slot_info.erase(p_idx); - update(); - connpos_dirty=true; + slot_info.erase(p_idx); + update(); + connpos_dirty=true; } void GraphNode::clear_all_slots(){ - slot_info.clear(); - update(); - connpos_dirty=true; + slot_info.clear(); + update(); + connpos_dirty=true; } bool GraphNode::is_slot_enabled_left(int p_idx) const{ - if (!slot_info.has(p_idx)) - return false; - return slot_info[p_idx].enable_left; + if (!slot_info.has(p_idx)) + return false; + return slot_info[p_idx].enable_left; } int GraphNode::get_slot_type_left(int p_idx) const{ - if (!slot_info.has(p_idx)) - return 0; - return slot_info[p_idx].type_left; + if (!slot_info.has(p_idx)) + return 0; + return slot_info[p_idx].type_left; } Color GraphNode::get_slot_color_left(int p_idx) const{ - if (!slot_info.has(p_idx)) - return Color(1,1,1,1); - return slot_info[p_idx].color_left; + if (!slot_info.has(p_idx)) + return Color(1,1,1,1); + return slot_info[p_idx].color_left; } bool GraphNode::is_slot_enabled_right(int p_idx) const{ - if (!slot_info.has(p_idx)) - return false; - return slot_info[p_idx].enable_right; + if (!slot_info.has(p_idx)) + return false; + return slot_info[p_idx].enable_right; } @@ -283,305 +283,305 @@ bool GraphNode::is_slot_enabled_right(int p_idx) const{ int GraphNode::get_slot_type_right(int p_idx) const{ - if (!slot_info.has(p_idx)) - return 0; - return slot_info[p_idx].type_right; + if (!slot_info.has(p_idx)) + return 0; + return slot_info[p_idx].type_right; } Color GraphNode::get_slot_color_right(int p_idx) const{ - if (!slot_info.has(p_idx)) - return Color(1,1,1,1); - return slot_info[p_idx].color_right; + if (!slot_info.has(p_idx)) + return Color(1,1,1,1); + return slot_info[p_idx].color_right; } Size2 GraphNode::get_minimum_size() const { - Ref title_font = get_font("title_font"); + Ref title_font = get_font("title_font"); - int sep=get_constant("separation"); - Ref sb=get_stylebox("frame"); - bool first=true; + int sep=get_constant("separation"); + Ref sb=get_stylebox("frame"); + bool first=true; - Size2 minsize; - minsize.x=title_font->get_string_size(title).x; - if (show_close) { - Ref close =get_icon("close"); - minsize.x+=sep+close->get_width(); - } + Size2 minsize; + minsize.x=title_font->get_string_size(title).x; + if (show_close) { + Ref close =get_icon("close"); + minsize.x+=sep+close->get_width(); + } - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + Control *c=get_child(i)->cast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - minsize.y+=size.y; - minsize.x=MAX(minsize.x,size.x); + minsize.y+=size.y; + minsize.x=MAX(minsize.x,size.x); - if (first) - first=false; - else - minsize.y+=sep; - } + if (first) + first=false; + else + minsize.y+=sep; + } - return minsize+sb->get_minimum_size(); + return minsize+sb->get_minimum_size(); } void GraphNode::set_title(const String& p_title) { - title=p_title; - minimum_size_changed(); - update(); + title=p_title; + minimum_size_changed(); + update(); } String GraphNode::get_title() const{ - return title; + return title; } void GraphNode::set_offset(const Vector2& p_offset) { - offset=p_offset; - emit_signal("offset_changed"); - update(); + offset=p_offset; + emit_signal("offset_changed"); + update(); } Vector2 GraphNode::get_offset() const { - return offset; + return offset; } void GraphNode::set_selected(bool p_selected) { - selected = p_selected; - update(); + selected = p_selected; + update(); } bool GraphNode::is_selected() { - return selected; + return selected; } void GraphNode::set_drag(bool p_drag) { - if (p_drag) - drag_from=get_offset(); - else - emit_signal("dragged",drag_from,get_offset()); //useful for undo/redo + if (p_drag) + drag_from=get_offset(); + else + emit_signal("dragged",drag_from,get_offset()); //useful for undo/redo } Vector2 GraphNode::get_drag_from() { - return drag_from; + return drag_from; } void GraphNode::set_show_close_button(bool p_enable){ - show_close=p_enable; - update(); + show_close=p_enable; + update(); } bool GraphNode::is_close_button_visible() const{ - return show_close; + return show_close; } void GraphNode::_connpos_update() { - int edgeofs=get_constant("port_offset"); - int sep=get_constant("separation"); + int edgeofs=get_constant("port_offset"); + int sep=get_constant("separation"); - Ref sb=get_stylebox("frame"); - conn_input_cache.clear(); - conn_output_cache.clear(); - int vofs=0; + Ref sb=get_stylebox("frame"); + conn_input_cache.clear(); + conn_output_cache.clear(); + int vofs=0; - int idx=0; + int idx=0; - for(int i=0;icast_to(); - if (!c) - continue; - if (c->is_set_as_toplevel()) - continue; + for(int i=0;icast_to(); + if (!c) + continue; + if (c->is_set_as_toplevel()) + continue; - Size2i size=c->get_combined_minimum_size(); + Size2i size=c->get_combined_minimum_size(); - int y = sb->get_margin(MARGIN_TOP)+vofs; - int h = size.y; + int y = sb->get_margin(MARGIN_TOP)+vofs; + int h = size.y; - if (slot_info.has(idx)) { + if (slot_info.has(idx)) { - if (slot_info[idx].enable_left) { - ConnCache cc; - cc.pos=Point2i(edgeofs,y+h/2); - cc.type=slot_info[idx].type_left; - cc.color=slot_info[idx].color_left; - conn_input_cache.push_back(cc); - } - if (slot_info[idx].enable_right) { - ConnCache cc; - cc.pos=Point2i(get_size().width-edgeofs,y+h/2); - cc.type=slot_info[idx].type_right; - cc.color=slot_info[idx].color_right; - conn_output_cache.push_back(cc); - } - } + if (slot_info[idx].enable_left) { + ConnCache cc; + cc.pos=Point2i(edgeofs,y+h/2); + cc.type=slot_info[idx].type_left; + cc.color=slot_info[idx].color_left; + conn_input_cache.push_back(cc); + } + if (slot_info[idx].enable_right) { + ConnCache cc; + cc.pos=Point2i(get_size().width-edgeofs,y+h/2); + cc.type=slot_info[idx].type_right; + cc.color=slot_info[idx].color_right; + conn_output_cache.push_back(cc); + } + } - if (vofs>0) - vofs+=sep; - vofs+=size.y; - idx++; + if (vofs>0) + vofs+=sep; + vofs+=size.y; + idx++; - } + } - connpos_dirty=false; + connpos_dirty=false; } int GraphNode::get_connection_input_count() { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - return conn_input_cache.size(); + return conn_input_cache.size(); } int GraphNode::get_connection_output_count() { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - return conn_output_cache.size(); + return conn_output_cache.size(); } Vector2 GraphNode::get_connection_input_pos(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Vector2()); - return conn_input_cache[p_idx].pos; + ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Vector2()); + return conn_input_cache[p_idx].pos; } int GraphNode::get_connection_input_type(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),0); - return conn_input_cache[p_idx].type; + ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),0); + return conn_input_cache[p_idx].type; } Color GraphNode::get_connection_input_color(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Color()); - return conn_input_cache[p_idx].color; + ERR_FAIL_INDEX_V(p_idx,conn_input_cache.size(),Color()); + return conn_input_cache[p_idx].color; } Vector2 GraphNode::get_connection_output_pos(int p_idx){ - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Vector2()); - return conn_output_cache[p_idx].pos; + ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Vector2()); + return conn_output_cache[p_idx].pos; } int GraphNode::get_connection_output_type(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),0); - return conn_output_cache[p_idx].type; + ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),0); + return conn_output_cache[p_idx].type; } Color GraphNode::get_connection_output_color(int p_idx) { - if (connpos_dirty) - _connpos_update(); + if (connpos_dirty) + _connpos_update(); - ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Color()); - return conn_output_cache[p_idx].color; + ERR_FAIL_INDEX_V(p_idx,conn_output_cache.size(),Color()); + return conn_output_cache[p_idx].color; } void GraphNode::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { + if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); - if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { - emit_signal("close_request"); - return; - } - emit_signal("raise_request"); + Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); + if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { + emit_signal("close_request"); + return; + } + emit_signal("raise_request"); - } + } } void GraphNode::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_title","title"),&GraphNode::set_title); - ObjectTypeDB::bind_method(_MD("get_title"),&GraphNode::get_title); - ObjectTypeDB::bind_method(_MD("_input_event"),&GraphNode::_input_event); + ObjectTypeDB::bind_method(_MD("set_title","title"),&GraphNode::set_title); + ObjectTypeDB::bind_method(_MD("get_title"),&GraphNode::get_title); + ObjectTypeDB::bind_method(_MD("_input_event"),&GraphNode::_input_event); - ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right"),&GraphNode::set_slot); - ObjectTypeDB::bind_method(_MD("clear_slot","idx"),&GraphNode::clear_slot); - ObjectTypeDB::bind_method(_MD("clear_all_slots","idx"),&GraphNode::clear_all_slots); - ObjectTypeDB::bind_method(_MD("is_slot_enabled_left","idx"),&GraphNode::is_slot_enabled_left); - ObjectTypeDB::bind_method(_MD("get_slot_type_left","idx"),&GraphNode::get_slot_type_left); - ObjectTypeDB::bind_method(_MD("get_slot_color_left","idx"),&GraphNode::get_slot_color_left); - ObjectTypeDB::bind_method(_MD("is_slot_enabled_right","idx"),&GraphNode::is_slot_enabled_right); - ObjectTypeDB::bind_method(_MD("get_slot_type_right","idx"),&GraphNode::get_slot_type_right); - ObjectTypeDB::bind_method(_MD("get_slot_color_right","idx"),&GraphNode::get_slot_color_right); + ObjectTypeDB::bind_method(_MD("set_slot","idx","enable_left","type_left","color_left","enable_right","type_right","color_right"),&GraphNode::set_slot); + ObjectTypeDB::bind_method(_MD("clear_slot","idx"),&GraphNode::clear_slot); + ObjectTypeDB::bind_method(_MD("clear_all_slots","idx"),&GraphNode::clear_all_slots); + ObjectTypeDB::bind_method(_MD("is_slot_enabled_left","idx"),&GraphNode::is_slot_enabled_left); + ObjectTypeDB::bind_method(_MD("get_slot_type_left","idx"),&GraphNode::get_slot_type_left); + ObjectTypeDB::bind_method(_MD("get_slot_color_left","idx"),&GraphNode::get_slot_color_left); + ObjectTypeDB::bind_method(_MD("is_slot_enabled_right","idx"),&GraphNode::is_slot_enabled_right); + ObjectTypeDB::bind_method(_MD("get_slot_type_right","idx"),&GraphNode::get_slot_type_right); + ObjectTypeDB::bind_method(_MD("get_slot_color_right","idx"),&GraphNode::get_slot_color_right); - ObjectTypeDB::bind_method(_MD("set_offset","offset"),&GraphNode::set_offset); - ObjectTypeDB::bind_method(_MD("get_offset"),&GraphNode::get_offset); + ObjectTypeDB::bind_method(_MD("set_offset","offset"),&GraphNode::set_offset); + ObjectTypeDB::bind_method(_MD("get_offset"),&GraphNode::get_offset); - ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count); - ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count); + ObjectTypeDB::bind_method(_MD("get_connection_output_count"),&GraphNode::get_connection_output_count); + ObjectTypeDB::bind_method(_MD("get_connection_input_count"),&GraphNode::get_connection_input_count); - ObjectTypeDB::bind_method(_MD("get_connection_output_pos","idx"),&GraphNode::get_connection_output_pos); - ObjectTypeDB::bind_method(_MD("get_connection_output_type","idx"),&GraphNode::get_connection_output_type); - ObjectTypeDB::bind_method(_MD("get_connection_output_color","idx"),&GraphNode::get_connection_output_color); - ObjectTypeDB::bind_method(_MD("get_connection_input_pos","idx"),&GraphNode::get_connection_input_pos); - ObjectTypeDB::bind_method(_MD("get_connection_input_type","idx"),&GraphNode::get_connection_input_type); - ObjectTypeDB::bind_method(_MD("get_connection_input_color","idx"),&GraphNode::get_connection_input_color); + ObjectTypeDB::bind_method(_MD("get_connection_output_pos","idx"),&GraphNode::get_connection_output_pos); + ObjectTypeDB::bind_method(_MD("get_connection_output_type","idx"),&GraphNode::get_connection_output_type); + ObjectTypeDB::bind_method(_MD("get_connection_output_color","idx"),&GraphNode::get_connection_output_color); + ObjectTypeDB::bind_method(_MD("get_connection_input_pos","idx"),&GraphNode::get_connection_input_pos); + ObjectTypeDB::bind_method(_MD("get_connection_input_type","idx"),&GraphNode::get_connection_input_type); + ObjectTypeDB::bind_method(_MD("get_connection_input_color","idx"),&GraphNode::get_connection_input_color); - ObjectTypeDB::bind_method(_MD("set_show_close_button","show"),&GraphNode::set_show_close_button); - ObjectTypeDB::bind_method(_MD("is_close_button_visible"),&GraphNode::is_close_button_visible); + ObjectTypeDB::bind_method(_MD("set_show_close_button","show"),&GraphNode::set_show_close_button); + ObjectTypeDB::bind_method(_MD("is_close_button_visible"),&GraphNode::is_close_button_visible); - ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"show_close"),_SCS("set_show_close_button"),_SCS("is_close_button_visible")); + ADD_PROPERTY( PropertyInfo(Variant::STRING,"title"),_SCS("set_title"),_SCS("get_title")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"show_close"),_SCS("set_show_close_button"),_SCS("is_close_button_visible")); - ADD_SIGNAL(MethodInfo("offset_changed")); - ADD_SIGNAL(MethodInfo("dragged",PropertyInfo(Variant::VECTOR2,"from"),PropertyInfo(Variant::VECTOR2,"to"))); - ADD_SIGNAL(MethodInfo("raise_request")); - ADD_SIGNAL(MethodInfo("close_request")); + ADD_SIGNAL(MethodInfo("offset_changed")); + ADD_SIGNAL(MethodInfo("dragged",PropertyInfo(Variant::VECTOR2,"from"),PropertyInfo(Variant::VECTOR2,"to"))); + ADD_SIGNAL(MethodInfo("raise_request")); + ADD_SIGNAL(MethodInfo("close_request")); } GraphNode::GraphNode() { - show_close=false; - connpos_dirty=true; + show_close=false; + connpos_dirty=true; } diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h index 6bece22ac5..201529380d 100644 --- a/scene/gui/graph_node.h +++ b/scene/gui/graph_node.h @@ -5,101 +5,101 @@ class GraphNode : public Container { - OBJ_TYPE(GraphNode,Container); + OBJ_TYPE(GraphNode,Container); - struct Slot { - bool enable_left; - int type_left; - Color color_left; - bool enable_right; - int type_right; - Color color_right; + struct Slot { + bool enable_left; + int type_left; + Color color_left; + bool enable_right; + int type_right; + Color color_right; - Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); } - }; + Slot() { enable_left=false; type_left=0; color_left=Color(1,1,1,1); enable_right=false; type_right=0; color_right=Color(1,1,1,1); } + }; - String title; - bool show_close; - Vector2 offset; + String title; + bool show_close; + Vector2 offset; - Rect2 close_rect; + Rect2 close_rect; - Vector cache_y; + Vector cache_y; - struct ConnCache { - Vector2 pos; - int type; - Color color; - }; + struct ConnCache { + Vector2 pos; + int type; + Color color; + }; - Vector conn_input_cache; - Vector conn_output_cache; + Vector conn_input_cache; + Vector conn_output_cache; - Map slot_info; + Map slot_info; - bool connpos_dirty; + bool connpos_dirty; - void _connpos_update(); - void _resort(); + void _connpos_update(); + void _resort(); - Vector2 drag_from; - bool selected; + Vector2 drag_from; + bool selected; protected: - void _input_event(const InputEvent& p_ev); - void _notification(int p_what); - static void _bind_methods(); + void _input_event(const InputEvent& p_ev); + void _notification(int p_what); + static void _bind_methods(); - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List *p_list) const; + bool _set(const StringName& p_name, const Variant& p_value); + bool _get(const StringName& p_name,Variant &r_ret) const; + void _get_property_list( List *p_list) const; public: - void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right); - void clear_slot(int p_idx); - void clear_all_slots(); - bool is_slot_enabled_left(int p_idx) const; - int get_slot_type_left(int p_idx) const; - Color get_slot_color_left(int p_idx) const; - bool is_slot_enabled_right(int p_idx) const; - int get_slot_type_right(int p_idx) const; - Color get_slot_color_right(int p_idx) const; + void set_slot(int p_idx,bool p_enable_left,int p_type_left,const Color& p_color_left, bool p_enable_right,int p_type_right,const Color& p_color_right); + void clear_slot(int p_idx); + void clear_all_slots(); + bool is_slot_enabled_left(int p_idx) const; + int get_slot_type_left(int p_idx) const; + Color get_slot_color_left(int p_idx) const; + bool is_slot_enabled_right(int p_idx) const; + int get_slot_type_right(int p_idx) const; + Color get_slot_color_right(int p_idx) const; - void set_title(const String& p_title); - String get_title() const; + void set_title(const String& p_title); + String get_title() const; - void set_offset(const Vector2& p_offset); - Vector2 get_offset() const; + void set_offset(const Vector2& p_offset); + Vector2 get_offset() const; - void set_selected(bool p_selected); - bool is_selected(); + void set_selected(bool p_selected); + bool is_selected(); - void set_drag(bool p_drag); - Vector2 get_drag_from(); + void set_drag(bool p_drag); + Vector2 get_drag_from(); - void set_show_close_button(bool p_enable); - bool is_close_button_visible() const; + void set_show_close_button(bool p_enable); + bool is_close_button_visible() const; - int get_connection_input_count() ; - int get_connection_output_count() ; - Vector2 get_connection_input_pos(int p_idx); - int get_connection_input_type(int p_idx); - Color get_connection_input_color(int p_idx); - Vector2 get_connection_output_pos(int p_idx); - int get_connection_output_type(int p_idx); - Color get_connection_output_color(int p_idx); + int get_connection_input_count() ; + int get_connection_output_count() ; + Vector2 get_connection_input_pos(int p_idx); + int get_connection_input_type(int p_idx); + Color get_connection_input_color(int p_idx); + Vector2 get_connection_output_pos(int p_idx); + int get_connection_output_type(int p_idx); + Color get_connection_output_color(int p_idx); - virtual Size2 get_minimum_size() const; + virtual Size2 get_minimum_size() const; - GraphNode(); + GraphNode(); }; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 667dfd4632..58ba5fba25 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -31,7 +31,7 @@ static TexCacheMap *tex_cache; template static Ref make_stylebox(T p_src,float p_left, float p_top, float p_right, float p_botton,float p_margin_left=-1, float p_margin_top=-1, float p_margin_right=-1, float p_margin_botton=-1, bool p_draw_center=true) { - + Ref texture; @@ -56,17 +56,17 @@ static Ref make_stylebox(T p_src,float p_left, float p_top, flo style->set_default_margin( MARGIN_BOTTOM, p_margin_botton ); style->set_default_margin( MARGIN_TOP, p_margin_top ); style->set_draw_center(p_draw_center); - + return style; } template static Ref make_icon(T p_src) { - - + + Ref texture( memnew( ImageTexture ) ); texture->create_from_image( Image(p_src),ImageTexture::FLAG_FILTER ); - + return texture; } @@ -75,7 +75,7 @@ static Ref make_font(int p_height,int p_ascent, int p_valign, int p_charco Ref font( memnew( Font ) ); font->add_texture( p_texture ); - + for (int i=0;i make_font(int p_height,int p_ascent, int p_valign, int p_charco font->add_char( chr, 0, frect, align,advance ); - + } - + font->set_height( p_height ); font->set_ascent( p_ascent ); @@ -152,12 +152,12 @@ static Ref make_font2(int p_height,int p_ascent, int p_charcount, const in static Ref make_empty_stylebox(float p_margin_left=-1, float p_margin_top=-1, float p_margin_right=-1, float p_margin_botton=-1) { Ref style( memnew( StyleBoxEmpty) ); - + style->set_default_margin( MARGIN_LEFT, p_margin_left ); style->set_default_margin( MARGIN_RIGHT, p_margin_right ); style->set_default_margin( MARGIN_BOTTOM, p_margin_botton ); style->set_default_margin( MARGIN_TOP, p_margin_top ); - + return style; } @@ -300,49 +300,49 @@ void make_default_theme() { t->set_constant("hseparation","MenuButton", 0 ); - // CheckBox + // CheckBox - Ref cbx_empty = memnew( StyleBoxEmpty ); - cbx_empty->set_default_margin(MARGIN_LEFT,22); - cbx_empty->set_default_margin(MARGIN_RIGHT,4); - cbx_empty->set_default_margin(MARGIN_TOP,4); - cbx_empty->set_default_margin(MARGIN_BOTTOM,5); - Ref cbx_focus = focus; - cbx_focus->set_default_margin(MARGIN_LEFT,4); - cbx_focus->set_default_margin(MARGIN_RIGHT,22); - cbx_focus->set_default_margin(MARGIN_TOP,4); - cbx_focus->set_default_margin(MARGIN_BOTTOM,5); + Ref cbx_empty = memnew( StyleBoxEmpty ); + cbx_empty->set_default_margin(MARGIN_LEFT,22); + cbx_empty->set_default_margin(MARGIN_RIGHT,4); + cbx_empty->set_default_margin(MARGIN_TOP,4); + cbx_empty->set_default_margin(MARGIN_BOTTOM,5); + Ref cbx_focus = focus; + cbx_focus->set_default_margin(MARGIN_LEFT,4); + cbx_focus->set_default_margin(MARGIN_RIGHT,22); + cbx_focus->set_default_margin(MARGIN_TOP,4); + cbx_focus->set_default_margin(MARGIN_BOTTOM,5); - t->set_stylebox("normal","CheckBox", cbx_empty ); - t->set_stylebox("pressed","CheckBox", cbx_empty ); - t->set_stylebox("disabled","CheckBox", cbx_empty ); - t->set_stylebox("hover","CheckBox", cbx_empty ); - t->set_stylebox("focus","CheckBox", cbx_focus ); + t->set_stylebox("normal","CheckBox", cbx_empty ); + t->set_stylebox("pressed","CheckBox", cbx_empty ); + t->set_stylebox("disabled","CheckBox", cbx_empty ); + t->set_stylebox("hover","CheckBox", cbx_empty ); + t->set_stylebox("focus","CheckBox", cbx_focus ); - t->set_icon("checked", "CheckBox", make_icon(checked_png)); - t->set_icon("unchecked", "CheckBox", make_icon(unchecked_png)); - t->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png)); - t->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png)); + t->set_icon("checked", "CheckBox", make_icon(checked_png)); + t->set_icon("unchecked", "CheckBox", make_icon(unchecked_png)); + t->set_icon("radio_checked", "CheckBox", make_icon(radio_checked_png)); + t->set_icon("radio_unchecked", "CheckBox", make_icon(radio_unchecked_png)); - t->set_font("font","CheckBox", default_font ); + t->set_font("font","CheckBox", default_font ); - t->set_color("font_color","CheckBox", control_font_color ); - t->set_color("font_color_pressed","CheckBox", control_font_color_pressed ); - t->set_color("font_color_hover","CheckBox", control_font_color_hover ); - t->set_color("font_color_disabled","CheckBox", control_font_color_disabled ); + t->set_color("font_color","CheckBox", control_font_color ); + t->set_color("font_color_pressed","CheckBox", control_font_color_pressed ); + t->set_color("font_color_hover","CheckBox", control_font_color_hover ); + t->set_color("font_color_disabled","CheckBox", control_font_color_disabled ); - t->set_constant("hseparation","CheckBox",4); - t->set_constant("check_vadjust","CheckBox",0); + t->set_constant("hseparation","CheckBox",4); + t->set_constant("check_vadjust","CheckBox",0); // CheckButton - + Ref cb_empty = memnew( StyleBoxEmpty ); cb_empty->set_default_margin(MARGIN_LEFT,6); cb_empty->set_default_margin(MARGIN_RIGHT,70); cb_empty->set_default_margin(MARGIN_TOP,4); - cb_empty->set_default_margin(MARGIN_BOTTOM,4); + cb_empty->set_default_margin(MARGIN_BOTTOM,4); t->set_stylebox("normal","CheckButton", cb_empty ); t->set_stylebox("pressed","CheckButton", cb_empty ); @@ -366,7 +366,7 @@ void make_default_theme() { // Label - + t->set_font("font","Label", default_font ); t->set_color("font_color","Label", Color(1,1,1) ); @@ -558,11 +558,11 @@ void make_default_theme() { // GraphNode Ref graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5); - Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5); + Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5); //graphsb->set_expand_margin_size(MARGIN_LEFT,10); //graphsb->set_expand_margin_size(MARGIN_RIGHT,10); t->set_stylebox("frame","GraphNode", graphsb ); - t->set_stylebox("selectedframe","GraphNode", graphsbselected ); + t->set_stylebox("selectedframe","GraphNode", graphsbselected ); t->set_constant("separation","GraphNode", 1 ); t->set_icon("port","GraphNode", make_icon( graph_port_png ) ); t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) ); @@ -713,7 +713,7 @@ void make_default_theme() { // FileDialog - + t->set_icon("folder","FileDialog",make_icon(icon_folder_png)); t->set_color("files_disabled","FileDialog",Color(0,0,0,0.7)); @@ -877,10 +877,10 @@ void make_default_theme() { #endif void clear_default_theme() { - + Theme::set_default( Ref() ); Theme::set_default_icon( Ref< Texture >() ); - Theme::set_default_style( Ref< StyleBox >() ); + Theme::set_default_style( Ref< StyleBox >() ); Theme::set_default_font( Ref< Font >() ); } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index a0f7edbd93..6e95432b99 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -37,596 +37,596 @@ void GraphColorRampEdit::_input_event(const InputEvent& p_event) { - if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { - - points.remove(grabbed); - grabbed=-1; - update(); - emit_signal("ramp_changed"); - accept_event(); - } - - if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { + + points.remove(grabbed); + grabbed=-1; + update(); + emit_signal("ramp_changed"); + accept_event(); + } + + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { - update(); - int x = p_event.mouse_button.x; - int total_w = get_size().width-get_size().height-3; - if (x>total_w+3) { - - if (grabbed==-1) - return; - Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10); - picker->set_color(points[grabbed].color); - popup->set_pos(get_global_pos()-Size2(0,ms.height)); - popup->set_size(ms); - popup->popup(); - return; - } - - - float ofs = CLAMP(x/float(total_w),0,1); - - grabbed=-1; - grabbing=true; - int pos=-1; - for(int i=0;itotal_w+3) { + + if (grabbed==-1) + return; + Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10); + picker->set_color(points[grabbed].color); + popup->set_pos(get_global_pos()-Size2(0,ms.height)); + popup->set_size(ms); + popup->popup(); + return; + } + + + float ofs = CLAMP(x/float(total_w),0,1); + + grabbed=-1; + grabbing=true; + int pos=-1; + for(int i=0;iconnect("color_changed",this,"_color_changed"); - } - if (p_what==NOTIFICATION_DRAW) { + if (p_what==NOTIFICATION_ENTER_TREE) { + picker->connect("color_changed",this,"_color_changed"); + } + if (p_what==NOTIFICATION_DRAW) { - Point prev; - prev.offset=0; - prev.color=Color(0,0,0); - int w = get_size().x; - int h = get_size().y; + Point prev; + prev.offset=0; + prev.color=Color(0,0,0); + int w = get_size().x; + int h = get_size().y; - int total_w = get_size().width-get_size().height-3; + int total_w = get_size().width-get_size().height-3; - for(int i=-1;i points; - Vector colors; - points.push_back(Vector2(prev.offset*total_w,h)); - points.push_back(Vector2(prev.offset*total_w,0)); - points.push_back(Vector2(next.offset*total_w,0)); - points.push_back(Vector2(next.offset*total_w,h)); - colors.push_back(prev.color); - colors.push_back(prev.color); - colors.push_back(next.color); - colors.push_back(next.color); - draw_primitive(points,colors,Vector()); - prev=next; - } + Vector points; + Vector colors; + points.push_back(Vector2(prev.offset*total_w,h)); + points.push_back(Vector2(prev.offset*total_w,0)); + points.push_back(Vector2(next.offset*total_w,0)); + points.push_back(Vector2(next.offset*total_w,h)); + colors.push_back(prev.color); + colors.push_back(prev.color); + colors.push_back(next.color); + colors.push_back(next.color); + draw_primitive(points,colors,Vector()); + prev=next; + } - for(int i=0;i& p_offsets,const Vector& p_colors) { - ERR_FAIL_COND(p_offsets.size()!=p_colors.size()); - points.clear(); - for(int i=0;i GraphColorRampEdit::get_offsets() const{ - Vector ret; - for(int i=0;i ret; + for(int i=0;i GraphColorRampEdit::get_colors() const{ - Vector ret; - for(int i=0;i ret; + for(int i=0;iadd_child(picker); - popup->set_child_rect(picker); - add_child(popup); + popup = memnew( PopupPanel ); + picker = memnew( ColorPicker ); + popup->add_child(picker); + popup->set_child_rect(picker); + add_child(popup); } //////////// void GraphCurveMapEdit::_input_event(const InputEvent& p_event) { - if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { + if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) { - points.remove(grabbed); - grabbed=-1; - update(); - emit_signal("curve_changed"); - accept_event(); - } + points.remove(grabbed); + grabbed=-1; + update(); + emit_signal("curve_changed"); + accept_event(); + } - if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { + if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) { - update(); - Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size(); - p.y=1.0-p.y; - grabbed=-1; - grabbing=true; + update(); + Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size(); + p.y=1.0-p.y; + grabbed=-1; + grabbing=true; - for(int i=0;icurve[cd->outline][lastx] = lasty; - } - else - { - cd->curve_ptr[cd->outline][lastx] = lasty; - if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax); - } + float geometry[4][4]; + float tmp1[4][4]; + float tmp2[4][4]; + float deltas[4][4]; + double x, dx, dx2, dx3; + double y, dy, dy2, dy3; + double d, d2, d3; + int lastx, lasty; + int newx, newy; + int ntimes; + int i,j; + + int xmax=get_size().x; + int ymax=get_size().y; + + /* construct the geometry matrix from the segment */ + for (i = 0; i < 4; i++) { + geometry[i][2] = 0; + geometry[i][3] = 0; + } + + geometry[0][0] = (p_a[0] * xmax); + geometry[1][0] = (p_b[0] * xmax); + geometry[2][0] = (p_c[0] * xmax); + geometry[3][0] = (p_d[0] * xmax); + + geometry[0][1] = (p_a[1] * ymax); + geometry[1][1] = (p_b[1] * ymax); + geometry[2][1] = (p_c[1] * ymax); + geometry[3][1] = (p_d[1] * ymax); + + /* subdivide the curve ntimes (1000) times */ + ntimes = 4 * xmax; + /* ntimes can be adjusted to give a finer or coarser curve */ + d = 1.0 / ntimes; + d2 = d * d; + d3 = d * d * d; + + /* construct a temporary matrix for determining the forward differencing deltas */ + tmp2[0][0] = 0; tmp2[0][1] = 0; tmp2[0][2] = 0; tmp2[0][3] = 1; + tmp2[1][0] = d3; tmp2[1][1] = d2; tmp2[1][2] = d; tmp2[1][3] = 0; + tmp2[2][0] = 6*d3; tmp2[2][1] = 2*d2; tmp2[2][2] = 0; tmp2[2][3] = 0; + tmp2[3][0] = 6*d3; tmp2[3][1] = 0; tmp2[3][2] = 0; tmp2[3][3] = 0; + + /* compose the basis and geometry matrices */ + + static const float CR_basis[4][4] = + { + { -0.5, 1.5, -1.5, 0.5 }, + { 1.0, -2.5, 2.0, -0.5 }, + { -0.5, 0.0, 0.5, 0.0 }, + { 0.0, 1.0, 0.0, 0.0 }, + }; + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + tmp1[i][j] = (CR_basis[i][0] * geometry[0][j] + + CR_basis[i][1] * geometry[1][j] + + CR_basis[i][2] * geometry[2][j] + + CR_basis[i][3] * geometry[3][j]); + } + } + /* compose the above results to get the deltas matrix */ + + for (i = 0; i < 4; i++) + { + for (j = 0; j < 4; j++) + { + deltas[i][j] = (tmp2[i][0] * tmp1[0][j] + + tmp2[i][1] * tmp1[1][j] + + tmp2[i][2] * tmp1[2][j] + + tmp2[i][3] * tmp1[3][j]); + } + } + + + /* extract the x deltas */ + x = deltas[0][0]; + dx = deltas[1][0]; + dx2 = deltas[2][0]; + dx3 = deltas[3][0]; + + /* extract the y deltas */ + y = deltas[0][1]; + dy = deltas[1][1]; + dy2 = deltas[2][1]; + dy3 = deltas[3][1]; + + + lastx = CLAMP (x, 0, xmax); + lasty = CLAMP (y, 0, ymax); + + /* if (fix255) + { + cd->curve[cd->outline][lastx] = lasty; + } + else + { + cd->curve_ptr[cd->outline][lastx] = lasty; + if(gb_debug) printf("bender_plot_curve xmax:%d ymax:%d\n", (int)xmax, (int)ymax); + } */ - /* loop over the curve */ - for (i = 0; i < ntimes; i++) - { - /* increment the x values */ - x += dx; - dx += dx2; - dx2 += dx3; - - /* increment the y values */ - y += dy; - dy += dy2; - dy2 += dy3; - - newx = CLAMP ((Math::round (x)), 0, xmax); - newy = CLAMP ((Math::round (y)), 0, ymax); - - /* if this point is different than the last one...then draw it */ - if ((lastx != newx) || (lasty != newy)) - { + /* loop over the curve */ + for (i = 0; i < ntimes; i++) + { + /* increment the x values */ + x += dx; + dx += dx2; + dx2 += dx3; + + /* increment the y values */ + y += dy; + dy += dy2; + dy2 += dy3; + + newx = CLAMP ((Math::round (x)), 0, xmax); + newy = CLAMP ((Math::round (y)), 0, ymax); + + /* if this point is different than the last one...then draw it */ + if ((lastx != newx) || (lasty != newy)) + { #if 0 - if(fix255) - { - /* use fixed array size (for the curve graph) */ - cd->curve[cd->outline][newx] = newy; - } - else - { - /* use dynamic allocated curve_ptr (for the real curve) */ - cd->curve_ptr[cd->outline][newx] = newy; - - if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy); - } + if(fix255) + { + /* use fixed array size (for the curve graph) */ + cd->curve[cd->outline][newx] = newy; + } + else + { + /* use dynamic allocated curve_ptr (for the real curve) */ + cd->curve_ptr[cd->outline][newx] = newy; + + if(gb_debug) printf("outline: %d cX: %d cY: %d\n", (int)cd->outline, (int)newx, (int)newy); + } #endif - draw_line(Vector2(lastx,ymax-lasty),Vector2(newx,ymax-newy),Color(0.8,0.8,0.8,0.8),2.0); - } + draw_line(Vector2(lastx,ymax-lasty),Vector2(newx,ymax-newy),Color(0.8,0.8,0.8,0.8),2.0); + } - lastx = newx; - lasty = newy; - } + lastx = newx; + lasty = newy; + } } void GraphCurveMapEdit::_notification(int p_what){ - if (p_what==NOTIFICATION_DRAW) { + if (p_what==NOTIFICATION_DRAW) { - draw_style_box(get_stylebox("bg","Tree"),Rect2(Point2(),get_size())); + draw_style_box(get_stylebox("bg","Tree"),Rect2(Point2(),get_size())); - int w = get_size().x; - int h = get_size().y; + int w = get_size().x; + int h = get_size().y; - Vector2 prev=Vector2(0,0); - Vector2 prev2=Vector2(0,0); + Vector2 prev=Vector2(0,0); + Vector2 prev2=Vector2(0,0); - for(int i=-1;i=points.size()) { - next=Vector2(1,1); - } else { - next=Vector2(points[i+1].offset,points[i+1].height); - } + Vector2 next; + Vector2 next2; + if (i+1>=points.size()) { + next=Vector2(1,1); + } else { + next=Vector2(points[i+1].offset,points[i+1].height); + } - if (i+2>=points.size()) { - next2=Vector2(1,1); - } else { - next2=Vector2(points[i+2].offset,points[i+2].height); - } + if (i+2>=points.size()) { + next2=Vector2(1,1); + } else { + next2=Vector2(points[i+2].offset,points[i+2].height); + } - /*if (i==-1 && prev.offset==next.offset) { - prev=next; - continue; - }*/ + /*if (i==-1 && prev.offset==next.offset) { + prev=next; + continue; + }*/ - _plot_curve(prev2,prev,next,next2); + _plot_curve(prev2,prev,next,next2); - prev2=prev; - prev=next; - } + prev2=prev; + prev=next; + } - for(int i=0;i& p_points) { - points.clear(); - for(int i=0;i GraphCurveMapEdit::get_points() const { - Vector ret; - for(int i=0;i ret; + for(int i=0;iget_undo_redo(); - ur->create_action("Change Scalar Constant",true); - ur->add_do_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,p_value); - ur->add_undo_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,graph->scalar_const_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Constant",true); + ur->add_do_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,p_value); + ur->add_undo_method(graph.ptr(),"scalar_const_node_set_value",type,p_id,graph->scalar_const_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_const_changed(double p_value, int p_id,Array p_arr){ - Vector3 val; - for(int i=0;iget_undo_redo(); - ur->create_action("Change Vec Constant",true); - ur->add_do_method(graph.ptr(),"vec_const_node_set_value",type,p_id,val); - ur->add_undo_method(graph.ptr(),"vec_const_node_set_value",type,p_id,graph->vec_const_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Constant",true); + ur->add_do_method(graph.ptr(),"vec_const_node_set_value",type,p_id,val); + ur->add_undo_method(graph.ptr(),"vec_const_node_set_value",type,p_id,graph->vec_const_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_rgb_const_changed(const Color& p_color, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change RGB Constant",true); - ur->add_do_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,p_color); - ur->add_undo_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,graph->rgb_const_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change RGB Constant",true); + ur->add_do_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,p_color); + ur->add_undo_method(graph.ptr(),"rgb_const_node_set_value",type,p_id,graph->rgb_const_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_scalar_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Scalar Operator"); - ur->add_do_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,graph->scalar_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Operator"); + ur->add_do_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"scalar_op_node_set_op",type,p_id,graph->scalar_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Vec Operator"); - ur->add_do_method(graph.ptr(),"vec_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"vec_op_node_set_op",type,p_id,graph->vec_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Operator"); + ur->add_do_method(graph.ptr(),"vec_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"vec_op_node_set_op",type,p_id,graph->vec_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_scalar_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change VecxScalar Operator"); - ur->add_do_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,graph->vec_scalar_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change VecxScalar Operator"); + ur->add_do_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"vec_scalar_op_node_set_op",type,p_id,graph->vec_scalar_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_rgb_op_changed(int p_op, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change RGB Operator"); - ur->add_do_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,p_op); - ur->add_undo_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,graph->rgb_op_node_get_op(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change RGB Operator"); + ur->add_do_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,p_op); + ur->add_undo_method(graph.ptr(),"rgb_op_node_set_op",type,p_id,graph->rgb_op_node_get_op(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_xform_inv_rev_changed(bool p_enabled, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Toggle Rot Only"); - ur->add_do_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,p_enabled); - ur->add_undo_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,graph->xform_vec_mult_node_get_no_translation(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Toggle Rot Only"); + ur->add_do_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,p_enabled); + ur->add_undo_method(graph.ptr(),"xform_vec_mult_node_set_no_translation",type,p_id,graph->xform_vec_mult_node_get_no_translation(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_scalar_func_changed(int p_func, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Scalar Function"); - ur->add_do_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,p_func); - ur->add_undo_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,graph->scalar_func_node_get_function(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Function"); + ur->add_do_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,p_func); + ur->add_undo_method(graph.ptr(),"scalar_func_node_set_function",type,p_id,graph->scalar_func_node_get_function(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_func_changed(int p_func, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Vec Function"); - ur->add_do_method(graph.ptr(),"vec_func_node_set_function",type,p_id,p_func); - ur->add_undo_method(graph.ptr(),"vec_func_node_set_function",type,p_id,graph->vec_func_node_get_function(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Function"); + ur->add_do_method(graph.ptr(),"vec_func_node_set_function",type,p_id,p_func); + ur->add_undo_method(graph.ptr(),"vec_func_node_set_function",type,p_id,graph->vec_func_node_get_function(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_scalar_input_changed(double p_value,int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Scalar Uniform",true); - ur->add_do_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,p_value); - ur->add_undo_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,graph->scalar_input_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Scalar Uniform",true); + ur->add_do_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,p_value); + ur->add_undo_method(graph.ptr(),"scalar_input_node_set_value",type,p_id,graph->scalar_input_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_vec_input_changed(double p_value, int p_id,Array p_arr){ - Vector3 val; - for(int i=0;iget_undo_redo(); - ur->create_action("Change Vec Uniform",true); - ur->add_do_method(graph.ptr(),"vec_input_node_set_value",type,p_id,val); - ur->add_undo_method(graph.ptr(),"vec_input_node_set_value",type,p_id,graph->vec_input_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Vec Uniform",true); + ur->add_do_method(graph.ptr(),"vec_input_node_set_value",type,p_id,val); + ur->add_undo_method(graph.ptr(),"vec_input_node_set_value",type,p_id,graph->vec_input_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){ - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); - ped_popup->popup(); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); + ped_popup->popup(); } void ShaderGraphView::_xform_const_changed(int p_id, Node *p_button){ - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); - ped_popup->popup(); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); + ped_popup->popup(); } void ShaderGraphView::_rgb_input_changed(const Color& p_color, int p_id){ - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change RGB Uniform",true); - ur->add_do_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,p_color); - ur->add_undo_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,graph->rgb_input_node_get_value(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change RGB Uniform",true); + ur->add_do_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,p_color); + ur->add_undo_method(graph.ptr(),"rgb_input_node_set_value",type,p_id,graph->rgb_input_node_get_value(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_tex_input_change(int p_id, Node *p_button){ @@ -879,180 +879,180 @@ void ShaderGraphView::_cube_input_change(int p_id){ void ShaderGraphView::_variant_edited() { - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change XForm Uniform"); - ur->add_do_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,graph->xform_const_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change XForm Uniform"); + ur->add_do_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"xform_const_node_set_value",type,edited_id,graph->xform_const_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_INPUT) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_INPUT) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change XForm Uniform"); - ur->add_do_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,graph->xform_input_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change XForm Uniform"); + ur->add_do_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"xform_input_node_set_value",type,edited_id,graph->xform_input_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_TEXTURE_INPUT) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_TEXTURE_INPUT) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Texture Uniform"); - ur->add_do_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,graph->texture_input_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Texture Uniform"); + ur->add_do_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"texture_input_node_set_value",type,edited_id,graph->texture_input_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } - if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_CUBEMAP_INPUT) { + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_CUBEMAP_INPUT) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Cubemap Uniform"); - ur->add_do_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,ped_popup->get_variant()); - ur->add_undo_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,graph->cubemap_input_node_get_value(type,edited_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); - } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Cubemap Uniform"); + ur->add_do_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,ped_popup->get_variant()); + ur->add_undo_method(graph.ptr(),"cubemap_input_node_set_value",type,edited_id,graph->cubemap_input_node_get_value(type,edited_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + } } void ShaderGraphView::_comment_edited(int p_id,Node* p_button) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - TextEdit *te=p_button->cast_to(); - ur->create_action("Change Comment",true); - ur->add_do_method(graph.ptr(),"comment_node_set_text",type,p_id,te->get_text()); - ur->add_undo_method(graph.ptr(),"comment_node_set_text",type,p_id,graph->comment_node_get_text(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + TextEdit *te=p_button->cast_to(); + ur->create_action("Change Comment",true); + ur->add_do_method(graph.ptr(),"comment_node_set_text",type,p_id,te->get_text()); + ur->add_undo_method(graph.ptr(),"comment_node_set_text",type,p_id,graph->comment_node_get_text(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_color_ramp_changed(int p_id,Node* p_ramp) { - GraphColorRampEdit *cr=p_ramp->cast_to(); + GraphColorRampEdit *cr=p_ramp->cast_to(); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - Vector offsets=cr->get_offsets(); - Vector colors=cr->get_colors(); + Vector offsets=cr->get_offsets(); + Vector colors=cr->get_colors(); - DVector new_offsets; - DVector new_colors; - { - new_offsets.resize(offsets.size()); - new_colors.resize(colors.size()); - DVector::Write ow=new_offsets.write(); - DVector::Write cw=new_colors.write(); - for(int i=0;i new_offsets; + DVector new_colors; + { + new_offsets.resize(offsets.size()); + new_colors.resize(colors.size()); + DVector::Write ow=new_offsets.write(); + DVector::Write cw=new_colors.write(); + for(int i=0;i old_offsets=graph->color_ramp_node_get_offsets(type,p_id); - DVector old_colors=graph->color_ramp_node_get_colors(type,p_id); + DVector old_offsets=graph->color_ramp_node_get_offsets(type,p_id); + DVector old_colors=graph->color_ramp_node_get_colors(type,p_id); - if (old_offsets.size()!=new_offsets.size()) - ur->create_action("Add/Remove to Color Ramp"); - else - ur->create_action("Modify Color Ramp",true); + if (old_offsets.size()!=new_offsets.size()) + ur->create_action("Add/Remove to Color Ramp"); + else + ur->create_action("Modify Color Ramp",true); - ur->add_do_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,new_colors,new_offsets); - ur->add_undo_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,old_colors,old_offsets); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + ur->add_do_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,new_colors,new_offsets); + ur->add_undo_method(graph.ptr(),"color_ramp_node_set_ramp",type,p_id,old_colors,old_offsets); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_curve_changed(int p_id,Node* p_curve) { - GraphCurveMapEdit *cr=p_curve->cast_to(); + GraphCurveMapEdit *cr=p_curve->cast_to(); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - Vector points=cr->get_points(); + Vector points=cr->get_points(); - DVector new_points; - { - new_points.resize(points.size()); - DVector::Write ow=new_points.write(); - for(int i=0;i new_points; + { + new_points.resize(points.size()); + DVector::Write ow=new_points.write(); + for(int i=0;i old_points=graph->curve_map_node_get_points(type,p_id); + DVector old_points=graph->curve_map_node_get_points(type,p_id); - if (old_points.size()!=new_points.size()) - ur->create_action("Add/Remove to Curve Map"); - else - ur->create_action("Modify Curve Map",true); + if (old_points.size()!=new_points.size()) + ur->create_action("Add/Remove to Curve Map"); + else + ur->create_action("Modify Curve Map",true); - ur->add_do_method(graph.ptr(),"curve_map_node_set_points",type,p_id,new_points); - ur->add_undo_method(graph.ptr(),"curve_map_node_set_points",type,p_id,old_points); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; + ur->add_do_method(graph.ptr(),"curve_map_node_set_points",type,p_id,new_points); + ur->add_undo_method(graph.ptr(),"curve_map_node_set_points",type,p_id,old_points); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; } void ShaderGraphView::_input_name_changed(const String& p_name, int p_id, Node *p_line_edit) { - LineEdit *le=p_line_edit->cast_to(); - ERR_FAIL_COND(!le); + LineEdit *le=p_line_edit->cast_to(); + ERR_FAIL_COND(!le); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Change Input Name"); - ur->add_do_method(graph.ptr(),"input_node_set_name",type,p_id,p_name); - ur->add_undo_method(graph.ptr(),"input_node_set_name",type,p_id,graph->input_node_get_name(type,p_id)); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - block_update=true; - ur->commit_action(); - block_update=false; - le->set_text(graph->input_node_get_name(type,p_id)); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change Input Name"); + ur->add_do_method(graph.ptr(),"input_node_set_name",type,p_id,p_name); + ur->add_undo_method(graph.ptr(),"input_node_set_name",type,p_id,graph->input_node_get_name(type,p_id)); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + block_update=true; + ur->commit_action(); + block_update=false; + le->set_text(graph->input_node_get_name(type,p_id)); } void ShaderGraphView::_tex_edited(int p_id,Node* p_button) { - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture"); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture"); } void ShaderGraphView::_cube_edited(int p_id,Node* p_button) { - ToolButton *tb = p_button->cast_to(); - ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); - ped_popup->set_size(tb->get_size()); - edited_id=p_id; - ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"); + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"); } @@ -1061,994 +1061,994 @@ void ShaderGraphView::_cube_edited(int p_id,Node* p_button) { void ShaderGraphView::_connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - int from_idx=-1; - int to_idx=-1; - for (Map::Element *E=node_map.front();E;E=E->next()) { + int from_idx=-1; + int to_idx=-1; + for (Map::Element *E=node_map.front();E;E=E->next()) { - if (p_from==E->get()->get_name()) - from_idx=E->key(); - if (p_to==E->get()->get_name()) - to_idx=E->key(); - } + if (p_from==E->get()->get_name()) + from_idx=E->key(); + if (p_to==E->get()->get_name()) + to_idx=E->key(); + } - ERR_FAIL_COND(from_idx==-1); - ERR_FAIL_COND(to_idx==-1); + ERR_FAIL_COND(from_idx==-1); + ERR_FAIL_COND(to_idx==-1); - ur->create_action("Connect Graph Nodes"); + ur->create_action("Connect Graph Nodes"); - List conns; + List conns; - graph->get_node_connections(type,&conns); - //disconnect/reconnect dependencies - ur->add_undo_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - for(List::Element *E=conns.front();E;E=E->next()) { + graph->get_node_connections(type,&conns); + //disconnect/reconnect dependencies + ur->add_undo_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + for(List::Element *E=conns.front();E;E=E->next()) { - if (E->get().dst_id==to_idx && E->get().dst_slot==p_to_slot) { - ur->add_do_method(graph.ptr(),"disconnect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); - ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); - } - } - ur->add_do_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + if (E->get().dst_id==to_idx && E->get().dst_slot==p_to_slot) { + ur->add_do_method(graph.ptr(),"disconnect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + } + } + ur->add_do_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - int from_idx=-1; - int to_idx=-1; - for (Map::Element *E=node_map.front();E;E=E->next()) { + int from_idx=-1; + int to_idx=-1; + for (Map::Element *E=node_map.front();E;E=E->next()) { - if (p_from==E->get()->get_name()) - from_idx=E->key(); - if (p_to==E->get()->get_name()) - to_idx=E->key(); - } + if (p_from==E->get()->get_name()) + from_idx=E->key(); + if (p_to==E->get()->get_name()) + to_idx=E->key(); + } - ERR_FAIL_COND(from_idx==-1); - ERR_FAIL_COND(to_idx==-1); + ERR_FAIL_COND(from_idx==-1); + ERR_FAIL_COND(to_idx==-1); - if (!graph->is_node_connected(type,from_idx,p_from_slot,to_idx,p_to_slot)) - return; //nothing to disconnect + if (!graph->is_node_connected(type,from_idx,p_from_slot,to_idx,p_to_slot)) + return; //nothing to disconnect - ur->create_action("Disconnect Graph Nodes"); + ur->create_action("Disconnect Graph Nodes"); - List conns; + List conns; - graph->get_node_connections(type,&conns); - //disconnect/reconnect dependencies - ur->add_do_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - ur->add_undo_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + graph->get_node_connections(type,&conns); + //disconnect/reconnect dependencies + ur->add_do_method(graph.ptr(),"disconnect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_undo_method(graph.ptr(),"connect_node",type,from_idx,p_from_slot,to_idx,p_to_slot); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_node_removed(int p_id) { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Remove Shader Graph Node"); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Remove Shader Graph Node"); - ur->add_do_method(graph.ptr(),"node_remove",type,p_id); - ur->add_undo_method(graph.ptr(),"node_add",type,graph->node_get_type(type,p_id),p_id); - ur->add_undo_method(graph.ptr(),"node_set_state",type,p_id,graph->node_get_state(type,p_id)); - List conns; + ur->add_do_method(graph.ptr(),"node_remove",type,p_id); + ur->add_undo_method(graph.ptr(),"node_add",type,graph->node_get_type(type,p_id),p_id); + ur->add_undo_method(graph.ptr(),"node_set_state",type,p_id,graph->node_get_state(type,p_id)); + List conns; - graph->get_node_connections(type,&conns); - for(List::Element *E=conns.front();E;E=E->next()) { + graph->get_node_connections(type,&conns); + for(List::Element *E=conns.front();E;E=E->next()) { - if (E->get().dst_id==p_id || E->get().src_id==p_id) { - ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); - } - } - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + if (E->get().dst_id==p_id || E->get().src_id==p_id) { + ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + } + } + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_begin_node_move() { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Move Shader Graph Node"); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Move Shader Graph Node"); } void ShaderGraphView::_node_moved(const Vector2& p_from, const Vector2& p_to,int p_id) { - ERR_FAIL_COND(!node_map.has(p_id)); - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->add_do_method(this,"_move_node",p_id,p_to); - ur->add_undo_method(this,"_move_node",p_id,p_from); + ERR_FAIL_COND(!node_map.has(p_id)); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->add_do_method(this,"_move_node",p_id,p_to); + ur->add_undo_method(this,"_move_node",p_id,p_from); } void ShaderGraphView::_end_node_move() { - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->commit_action(); + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->commit_action(); } void ShaderGraphView::_move_node(int p_id,const Vector2& p_to) { - ERR_FAIL_COND(!node_map.has(p_id)); - node_map[p_id]->set_offset(p_to); - graph->node_set_pos(type,p_id,p_to); + ERR_FAIL_COND(!node_map.has(p_id)); + node_map[p_id]->set_offset(p_to); + graph->node_set_pos(type,p_id,p_to); } void ShaderGraphView::_create_node(int p_id) { - GraphNode *gn = memnew( GraphNode ); - gn->set_show_close_button(true); - Color typecol[4]={ - Color(0.9,0.4,1), - Color(0.8,1,0.2), - Color(1,0.2,0.2), - Color(0,1,1) - }; - - - switch(graph->node_get_type(type,p_id)) { - - case ShaderGraph::NODE_INPUT: { - - gn->set_title("Input"); - - List si; - ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); - - int idx=0; - for (List::Element *E=si.front();E;E=E->next()) { - ShaderGraph::SlotInfo& s=E->get(); - if (s.dir==ShaderGraph::SLOT_IN) { - - Label *l= memnew( Label ); - l->set_text(s.name); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - gn->set_slot(idx,false,0,Color(),true,s.type,typecol[s.type]); - idx++; - } - } - - } break; // all inputs (case Shader type dependent) - case ShaderGraph::NODE_SCALAR_CONST: { - gn->set_title("Scalar"); - SpinBox *sb = memnew( SpinBox ); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->scalar_const_node_get_value(type,p_id)); - sb->connect("value_changed",this,"_scalar_const_changed",varray(p_id)); - gn->add_child(sb); - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; //scalar constant - case ShaderGraph::NODE_VEC_CONST: { - - gn->set_title("Vector"); - Array v3p(true); - for(int i=0;i<3;i++) { - HBoxContainer *hbc = memnew( HBoxContainer ); - Label *l = memnew( Label ); - l->set_text(String::chr('X'+i)); - hbc->add_child(l); - SpinBox *sb = memnew( SpinBox ); - sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->vec_const_node_get_value(type,p_id)[i]); - sb->connect("value_changed",this,"_vec_const_changed",varray(p_id,v3p)); - v3p.push_back(sb); - hbc->add_child(sb); - gn->add_child(hbc); - } - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; //vec3 constant - case ShaderGraph::NODE_RGB_CONST: { - - gn->set_title("Color"); - ColorPickerButton *cpb = memnew( ColorPickerButton ); - cpb->set_color(graph->rgb_const_node_get_value(type,p_id)); - cpb->connect("color_changed",this,"_rgb_const_changed",varray(p_id)); - gn->add_child(cpb); - Label *l = memnew( Label ); - l->set_text("RGB"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; //rgb constant (shows a color picker instead) - case ShaderGraph::NODE_XFORM_CONST: { - gn->set_title("XForm"); - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_xform_const_changed",varray(p_id,edit)); - gn->add_child(edit); - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - - } break; // 4x4 matrix constant - case ShaderGraph::NODE_TIME: { - - gn->set_title("Time"); - Label *l = memnew( Label ); - l->set_text("(s)"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // time in seconds - case ShaderGraph::NODE_SCREEN_TEX: { - - gn->set_title("ScreenTex"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("RGB"))); - gn->add_child(hbc); - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) - case ShaderGraph::NODE_SCALAR_OP: { - - gn->set_title("ScalarOp"); - static const char* op_name[ShaderGraph::SCALAR_MAX_OP]={ - "Add", - "Sub", - "Mul", - "Div", - "Mod", - "Pow", - "Max", - "Min", - "Atan2" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->scalar_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_scalar_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - - } break; // scalar vs scalar op (mul: { } break; add: { } break; div: { } break; etc) - case ShaderGraph::NODE_VEC_OP: { - - gn->set_title("VecOp"); - static const char* op_name[ShaderGraph::VEC_MAX_OP]={ - "Add", - "Sub", - "Mul", - "Div", - "Mod", - "Pow", - "Max", - "Min", - "Cross" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->vec_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_vec_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - - } break; // vec3 vs vec3 op (mul: { } break;ad: { } break;div: { } break;crossprod: { } break;etc) - case ShaderGraph::NODE_VEC_SCALAR_OP: { - - gn->set_title("VecScalarOp"); - static const char* op_name[ShaderGraph::VEC_SCALAR_MAX_OP]={ - "Mul", - "Div", - "Pow", - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->vec_scalar_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_vec_scalar_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - - } break; // vec3 vs scalar op (mul: { } break; add: { } break; div: { } break; etc) - case ShaderGraph::NODE_RGB_OP: { - - gn->set_title("RGB Op"); - static const char* op_name[ShaderGraph::RGB_MAX_OP]={ - "Screen", - "Difference", - "Darken", - "Lighten", - "Overlay", - "Dodge", - "Burn", - "SoftLight", - "HardLight" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(op_name[i],i); - } - - ob->select(graph->rgb_op_node_get_op(type,p_id)); - ob->connect("item_selected",this,"_rgb_op_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; // vec3 vs vec3 rgb op (with scalar amount): { } break; like brighten: { } break; darken: { } break; burn: { } break; dodge: { } break; multiply: { } break; etc. - case ShaderGraph::NODE_XFORM_MULT: { - - gn->set_title("XFMult"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color()); - - - } break; // mat4 x mat4 - case ShaderGraph::NODE_XFORM_VEC_MULT: { - - gn->set_title("XFVecMult"); - - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); - button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); - button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); - - gn->add_child(button); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); - hbc->add_spacer(); - Label *l = memnew(Label("out")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - gn->add_child( memnew(Label("vec"))); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; - case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { - - gn->set_title("XFVecInvMult"); - - - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); - button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); - button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); - - gn->add_child(button); - - gn->add_child( memnew(Label("vec"))); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); - hbc->add_spacer(); - Label *l = memnew(Label("out")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - - } break; // mat4 x vec3 inverse mult (with no-translation option) - case ShaderGraph::NODE_SCALAR_FUNC: { - - gn->set_title("ScalarFunc"); - static const char* func_name[ShaderGraph::SCALAR_MAX_FUNC]={ - "Sin", - "Cos", - "Tan", - "ASin", - "ACos", - "ATan", - "SinH", - "CosH", - "TanH", - "Log", - "Exp", - "Sqrt", - "Abs", - "Sign", - "Floor", - "Round", - "Ceil", - "Frac", - "Satr", - "Neg" - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(func_name[i],i); - } - - ob->select(graph->scalar_func_node_get_function(type,p_id)); - ob->connect("item_selected",this,"_scalar_func_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // scalar function (sin: { } break; cos: { } break; etc) - case ShaderGraph::NODE_VEC_FUNC: { - - - - gn->set_title("VecFunc"); - static const char* func_name[ShaderGraph::VEC_MAX_FUNC]={ - "Normalize", - "Saturate", - "Negate", - "Reciprocal", - "RGB to HSV", - "HSV to RGB", - }; - - OptionButton *ob = memnew( OptionButton ); - for(int i=0;iadd_item(func_name[i],i); - } - - ob->select(graph->vec_func_node_get_function(type,p_id)); - ob->connect("item_selected",this,"_vec_func_changed",varray(p_id)); - gn->add_child(ob); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("in"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("out"))); - gn->add_child(hbc); - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // vector function (normalize: { } break; negate: { } break; reciprocal: { } break; rgb2hsv: { } break; hsv2rgb: { } break; etc: { } break; etc) - case ShaderGraph::NODE_VEC_LEN: { - gn->set_title("VecLength"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("len"))); - gn->add_child(hbc); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // vec3 length - case ShaderGraph::NODE_DOT_PROD: { - - gn->set_title("DotProduct"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("dp"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; // vec3 . vec3 (dot product -> scalar output) - case ShaderGraph::NODE_VEC_TO_SCALAR: { - - gn->set_title("Vec2Scalar"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("vec"))); - hbc->add_spacer(); - Label *l=memnew(Label("x")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - l=memnew(Label("y")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l ); - l=memnew(Label("z")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - - - } break; // 1 vec3 input: { } break; 3 scalar outputs - case ShaderGraph::NODE_SCALAR_TO_VEC: { - - gn->set_title("Scalar2Vec"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("x"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("vec"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - } break; // 3 scalar input: { } break; 1 vec3 output - case ShaderGraph::NODE_VEC_TO_XFORM: { - - gn->set_title("Vec2XForm"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("x"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("xf"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); - gn->add_child( memnew(Label("ofs"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - - } break; // 3 vec input: { } break; 1 xform output - case ShaderGraph::NODE_XFORM_TO_VEC: { - - gn->set_title("XForm2Vec"); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); - hbc->add_spacer(); - Label *l=memnew(Label("x")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - l=memnew(Label("y")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l ); - l=memnew(Label("z")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - l=memnew(Label("ofs")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // 3 vec input: { } break; 1 xform output - case ShaderGraph::NODE_SCALAR_INTERP: { - - gn->set_title("ScalarInterp"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("interp"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - - - } break; // scalar interpolation (with optional curve) - case ShaderGraph::NODE_VEC_INTERP: { - - gn->set_title("VecInterp"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); - hbc->add_spacer(); - hbc->add_child( memnew(Label("interp"))); - gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); + GraphNode *gn = memnew( GraphNode ); + gn->set_show_close_button(true); + Color typecol[4]={ + Color(0.9,0.4,1), + Color(0.8,1,0.2), + Color(1,0.2,0.2), + Color(0,1,1) + }; + + + switch(graph->node_get_type(type,p_id)) { + + case ShaderGraph::NODE_INPUT: { + + gn->set_title("Input"); + + List si; + ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); + + int idx=0; + for (List::Element *E=si.front();E;E=E->next()) { + ShaderGraph::SlotInfo& s=E->get(); + if (s.dir==ShaderGraph::SLOT_IN) { + + Label *l= memnew( Label ); + l->set_text(s.name); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + gn->set_slot(idx,false,0,Color(),true,s.type,typecol[s.type]); + idx++; + } + } + + } break; // all inputs (case Shader type dependent) + case ShaderGraph::NODE_SCALAR_CONST: { + gn->set_title("Scalar"); + SpinBox *sb = memnew( SpinBox ); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->scalar_const_node_get_value(type,p_id)); + sb->connect("value_changed",this,"_scalar_const_changed",varray(p_id)); + gn->add_child(sb); + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; //scalar constant + case ShaderGraph::NODE_VEC_CONST: { + + gn->set_title("Vector"); + Array v3p(true); + for(int i=0;i<3;i++) { + HBoxContainer *hbc = memnew( HBoxContainer ); + Label *l = memnew( Label ); + l->set_text(String::chr('X'+i)); + hbc->add_child(l); + SpinBox *sb = memnew( SpinBox ); + sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->vec_const_node_get_value(type,p_id)[i]); + sb->connect("value_changed",this,"_vec_const_changed",varray(p_id,v3p)); + v3p.push_back(sb); + hbc->add_child(sb); + gn->add_child(hbc); + } + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; //vec3 constant + case ShaderGraph::NODE_RGB_CONST: { + + gn->set_title("Color"); + ColorPickerButton *cpb = memnew( ColorPickerButton ); + cpb->set_color(graph->rgb_const_node_get_value(type,p_id)); + cpb->connect("color_changed",this,"_rgb_const_changed",varray(p_id)); + gn->add_child(cpb); + Label *l = memnew( Label ); + l->set_text("RGB"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; //rgb constant (shows a color picker instead) + case ShaderGraph::NODE_XFORM_CONST: { + gn->set_title("XForm"); + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_xform_const_changed",varray(p_id,edit)); + gn->add_child(edit); + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + + } break; // 4x4 matrix constant + case ShaderGraph::NODE_TIME: { + + gn->set_title("Time"); + Label *l = memnew( Label ); + l->set_text("(s)"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + gn->set_slot(0,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // time in seconds + case ShaderGraph::NODE_SCREEN_TEX: { + + gn->set_title("ScreenTex"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("RGB"))); + gn->add_child(hbc); + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) + case ShaderGraph::NODE_SCALAR_OP: { + + gn->set_title("ScalarOp"); + static const char* op_name[ShaderGraph::SCALAR_MAX_OP]={ + "Add", + "Sub", + "Mul", + "Div", + "Mod", + "Pow", + "Max", + "Min", + "Atan2" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->scalar_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_scalar_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + + } break; // scalar vs scalar op (mul: { } break; add: { } break; div: { } break; etc) + case ShaderGraph::NODE_VEC_OP: { + + gn->set_title("VecOp"); + static const char* op_name[ShaderGraph::VEC_MAX_OP]={ + "Add", + "Sub", + "Mul", + "Div", + "Mod", + "Pow", + "Max", + "Min", + "Cross" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->vec_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_vec_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + + } break; // vec3 vs vec3 op (mul: { } break;ad: { } break;div: { } break;crossprod: { } break;etc) + case ShaderGraph::NODE_VEC_SCALAR_OP: { + + gn->set_title("VecScalarOp"); + static const char* op_name[ShaderGraph::VEC_SCALAR_MAX_OP]={ + "Mul", + "Div", + "Pow", + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->vec_scalar_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_vec_scalar_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + + } break; // vec3 vs scalar op (mul: { } break; add: { } break; div: { } break; etc) + case ShaderGraph::NODE_RGB_OP: { + + gn->set_title("RGB Op"); + static const char* op_name[ShaderGraph::RGB_MAX_OP]={ + "Screen", + "Difference", + "Darken", + "Lighten", + "Overlay", + "Dodge", + "Burn", + "SoftLight", + "HardLight" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(op_name[i],i); + } + + ob->select(graph->rgb_op_node_get_op(type,p_id)); + ob->connect("item_selected",this,"_rgb_op_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; // vec3 vs vec3 rgb op (with scalar amount): { } break; like brighten: { } break; darken: { } break; burn: { } break; dodge: { } break; multiply: { } break; etc. + case ShaderGraph::NODE_XFORM_MULT: { + + gn->set_title("XFMult"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color()); + + + } break; // mat4 x mat4 + case ShaderGraph::NODE_XFORM_VEC_MULT: { + + gn->set_title("XFVecMult"); + + Button *button = memnew( Button("RotOnly")); + button->set_toggle_mode(true); + button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); + button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); + + gn->add_child(button); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l = memnew(Label("out")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + gn->add_child( memnew(Label("vec"))); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; + case ShaderGraph::NODE_XFORM_VEC_INV_MULT: { + + gn->set_title("XFVecInvMult"); + + + Button *button = memnew( Button("RotOnly")); + button->set_toggle_mode(true); + button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); + button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); + + gn->add_child(button); + + gn->add_child( memnew(Label("vec"))); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l = memnew(Label("out")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + + } break; // mat4 x vec3 inverse mult (with no-translation option) + case ShaderGraph::NODE_SCALAR_FUNC: { + + gn->set_title("ScalarFunc"); + static const char* func_name[ShaderGraph::SCALAR_MAX_FUNC]={ + "Sin", + "Cos", + "Tan", + "ASin", + "ACos", + "ATan", + "SinH", + "CosH", + "TanH", + "Log", + "Exp", + "Sqrt", + "Abs", + "Sign", + "Floor", + "Round", + "Ceil", + "Frac", + "Satr", + "Neg" + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(func_name[i],i); + } + + ob->select(graph->scalar_func_node_get_function(type,p_id)); + ob->connect("item_selected",this,"_scalar_func_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("in"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar function (sin: { } break; cos: { } break; etc) + case ShaderGraph::NODE_VEC_FUNC: { + + + + gn->set_title("VecFunc"); + static const char* func_name[ShaderGraph::VEC_MAX_FUNC]={ + "Normalize", + "Saturate", + "Negate", + "Reciprocal", + "RGB to HSV", + "HSV to RGB", + }; + + OptionButton *ob = memnew( OptionButton ); + for(int i=0;iadd_item(func_name[i],i); + } + + ob->select(graph->vec_func_node_get_function(type,p_id)); + ob->connect("item_selected",this,"_vec_func_changed",varray(p_id)); + gn->add_child(ob); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("in"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("out"))); + gn->add_child(hbc); + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // vector function (normalize: { } break; negate: { } break; reciprocal: { } break; rgb2hsv: { } break; hsv2rgb: { } break; etc: { } break; etc) + case ShaderGraph::NODE_VEC_LEN: { + gn->set_title("VecLength"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("in"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("len"))); + gn->add_child(hbc); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // vec3 length + case ShaderGraph::NODE_DOT_PROD: { + + gn->set_title("DotProduct"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("dp"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; // vec3 . vec3 (dot product -> scalar output) + case ShaderGraph::NODE_VEC_TO_SCALAR: { + + gn->set_title("Vec2Scalar"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("vec"))); + hbc->add_spacer(); + Label *l=memnew(Label("x")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("y")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l ); + l=memnew(Label("z")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + + + } break; // 1 vec3 input: { } break; 3 scalar outputs + case ShaderGraph::NODE_SCALAR_TO_VEC: { + + gn->set_title("Scalar2Vec"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("x"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("vec"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("y"))); + gn->add_child( memnew(Label("z"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + } break; // 3 scalar input: { } break; 1 vec3 output + case ShaderGraph::NODE_VEC_TO_XFORM: { + + gn->set_title("Vec2XForm"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("x"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("xf"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("y"))); + gn->add_child( memnew(Label("z"))); + gn->add_child( memnew(Label("ofs"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + + } break; // 3 vec input: { } break; 1 xform output + case ShaderGraph::NODE_XFORM_TO_VEC: { + + gn->set_title("XForm2Vec"); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("xf"))); + hbc->add_spacer(); + Label *l=memnew(Label("x")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("y")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l ); + l=memnew(Label("z")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + l=memnew(Label("ofs")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // 3 vec input: { } break; 1 xform output + case ShaderGraph::NODE_SCALAR_INTERP: { + + gn->set_title("ScalarInterp"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("interp"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + gn->add_child( memnew(Label("c"))); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + + + } break; // scalar interpolation (with optional curve) + case ShaderGraph::NODE_VEC_INTERP: { + + gn->set_title("VecInterp"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_child( memnew(Label("a"))); + hbc->add_spacer(); + hbc->add_child( memnew(Label("interp"))); + gn->add_child(hbc); + gn->add_child( memnew(Label("b"))); + gn->add_child( memnew(Label("c"))); - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); - } break; // vec3 interpolation (with optional curve) - case ShaderGraph::NODE_COLOR_RAMP: { - - gn->set_title("ColorRamp"); - GraphColorRampEdit * ramp = memnew( GraphColorRampEdit ); - - DVector offsets = graph->color_ramp_node_get_offsets(type,p_id); - DVector colors = graph->color_ramp_node_get_colors(type,p_id); - - int oc = offsets.size(); - - if (oc) { - DVector::Read rofs = offsets.read(); - DVector::Read rcol = colors.read(); - - Vector ofsv; - Vector colorv; - for(int i=0;iset_ramp(ofsv,colorv); - - } - - ramp->connect("ramp_changed",this,"_color_ramp_changed",varray(p_id,ramp)); - ramp->set_custom_minimum_size(Size2(128,1)); - gn->add_child(ramp); - - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); - hbc->add_spacer(); - Label *l=memnew(Label("rgb")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - l=memnew(Label("alpha")); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child( l); - - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(2,false,ShaderGraph::SLOT_MAX,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // scalar interpolation (with optional curve) - case ShaderGraph::NODE_CURVE_MAP: { - - gn->set_title("CurveMap"); - GraphCurveMapEdit * map = memnew( GraphCurveMapEdit ); - - DVector points = graph->curve_map_node_get_points(type,p_id); - - int oc = points.size(); - - if (oc) { - DVector::Read rofs = points.read(); - - - Vector ofsv; - for(int i=0;iset_points(ofsv); - - } - map->connect("curve_changed",this,"_curve_changed",varray(p_id,map)); - - //map->connect("map_changed",this,"_curve_map_changed",varray(p_id,map)); - map->set_custom_minimum_size(Size2(128,64)); - gn->add_child(map); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); - hbc->add_spacer(); - Label *l=memnew(Label("cmap")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child( l); - gn->add_child(hbc); - - - gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // scalar interpolation (with optional curve) - - case ShaderGraph::NODE_SCALAR_INPUT: { - - gn->set_title("ScalarUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - SpinBox *sb = memnew( SpinBox ); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->scalar_input_node_get_value(type,p_id)); - sb->connect("value_changed",this,"_scalar_input_changed",varray(p_id)); - gn->add_child(sb); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // scalar uniform (assignable in material) - case ShaderGraph::NODE_VEC_INPUT: { - - gn->set_title("VectorUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - Array v3p(true); - for(int i=0;i<3;i++) { - HBoxContainer *hbc = memnew( HBoxContainer ); - Label *l = memnew( Label ); - l->set_text(String::chr('X'+i)); - hbc->add_child(l); - SpinBox *sb = memnew( SpinBox ); - sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); - sb->set_min(-100000); - sb->set_max(100000); - sb->set_step(0.001); - sb->set_val(graph->vec_input_node_get_value(type,p_id)[i]); - sb->connect("value_changed",this,"_vec_input_changed",varray(p_id,v3p)); - v3p.push_back(sb); - hbc->add_child(sb); - gn->add_child(hbc); - } - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - - } break; // vec3 uniform (assignable in material) - case ShaderGraph::NODE_RGB_INPUT: { - - gn->set_title("ColorUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - ColorPickerButton *cpb = memnew( ColorPickerButton ); - cpb->set_color(graph->rgb_input_node_get_value(type,p_id)); - cpb->connect("color_changed",this,"_rgb_input_changed",varray(p_id)); - gn->add_child(cpb); - Label *l = memnew( Label ); - l->set_text("RGB"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // color uniform (assignable in material) - case ShaderGraph::NODE_XFORM_INPUT: { - gn->set_title("XFUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_xform_input_changed",varray(p_id,edit)); - gn->add_child(edit); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); - - } break; // mat4 uniform (assignable in material) - case ShaderGraph::NODE_TEXTURE_INPUT: { - - gn->set_title("TexUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - TextureFrame *tex = memnew( TextureFrame ); - tex->set_expand(true); - tex->set_custom_minimum_size(Size2(80,80)); - gn->add_child(tex); - tex->set_texture(graph->texture_input_node_get_value(type,p_id)); - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_tex_edited",varray(p_id,edit)); - gn->add_child(edit); - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - Label *l=memnew(Label("RGB")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child(l); - gn->add_child(hbc); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(4,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // texture input (assignable in material) - case ShaderGraph::NODE_CUBEMAP_INPUT: { - - gn->set_title("TexUniform"); - LineEdit *le = memnew( LineEdit ); - gn->add_child(le); - le->set_text(graph->input_node_get_name(type,p_id)); - le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); - - ToolButton *edit = memnew( ToolButton ); - edit->set_text("edit.."); - edit->connect("pressed",this,"_cube_edited",varray(p_id,edit)); - gn->add_child(edit); - - - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - Label *l=memnew(Label("RGB")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child(l); - gn->add_child(hbc); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - } break; // cubemap input (assignable in material) - case ShaderGraph::NODE_DEFAULT_TEXTURE: { - - gn->set_title("CanvasItemTex"); - HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); - hbc->add_spacer(); - Label *l=memnew(Label("RGB")); - l->set_align(Label::ALIGN_RIGHT); - hbc->add_child(l); - gn->add_child(hbc); - l = memnew( Label ); - l->set_text("Alpha"); - l->set_align(Label::ALIGN_RIGHT); - gn->add_child(l); - - gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); - gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); - - - } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) - - case ShaderGraph::NODE_OUTPUT: { - gn->set_title("Output"); - gn->set_show_close_button(false); - - List si; - ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); - - int idx=0; - for (List::Element *E=si.front();E;E=E->next()) { - ShaderGraph::SlotInfo& s=E->get(); - if (s.dir==ShaderGraph::SLOT_OUT) { - - Label *l= memnew( Label ); - l->set_text(s.name); - l->set_align(Label::ALIGN_LEFT); - gn->add_child(l); - gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); - idx++; - } - } - - } break; // output (case Shader type dependent) - case ShaderGraph::NODE_COMMENT: { - gn->set_title("Comment"); - TextEdit *te = memnew(TextEdit); - te->set_custom_minimum_size(Size2(100,100)); - gn->add_child(te); - te->set_text(graph->comment_node_get_text(type,p_id)); - te->connect("text_changed",this,"_comment_edited",varray(p_id,te)); - - } break; // comment - - - - } - - gn->connect("dragged",this,"_node_moved",varray(p_id)); - gn->connect("close_request",this,"_node_removed",varray(p_id),CONNECT_DEFERRED); - graph_edit->add_child(gn); - node_map[p_id]=gn; - gn->set_offset(graph->node_get_pos(type,p_id)); + } break; // vec3 interpolation (with optional curve) + case ShaderGraph::NODE_COLOR_RAMP: { + + gn->set_title("ColorRamp"); + GraphColorRampEdit * ramp = memnew( GraphColorRampEdit ); + + DVector offsets = graph->color_ramp_node_get_offsets(type,p_id); + DVector colors = graph->color_ramp_node_get_colors(type,p_id); + + int oc = offsets.size(); + + if (oc) { + DVector::Read rofs = offsets.read(); + DVector::Read rcol = colors.read(); + + Vector ofsv; + Vector colorv; + for(int i=0;iset_ramp(ofsv,colorv); + + } + + ramp->connect("ramp_changed",this,"_color_ramp_changed",varray(p_id,ramp)); + ramp->set_custom_minimum_size(Size2(128,1)); + gn->add_child(ramp); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("c"))); + hbc->add_spacer(); + Label *l=memnew(Label("rgb")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + l=memnew(Label("alpha")); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child( l); + + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(2,false,ShaderGraph::SLOT_MAX,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar interpolation (with optional curve) + case ShaderGraph::NODE_CURVE_MAP: { + + gn->set_title("CurveMap"); + GraphCurveMapEdit * map = memnew( GraphCurveMapEdit ); + + DVector points = graph->curve_map_node_get_points(type,p_id); + + int oc = points.size(); + + if (oc) { + DVector::Read rofs = points.read(); + + + Vector ofsv; + for(int i=0;iset_points(ofsv); + + } + map->connect("curve_changed",this,"_curve_changed",varray(p_id,map)); + + //map->connect("map_changed",this,"_curve_map_changed",varray(p_id,map)); + map->set_custom_minimum_size(Size2(128,64)); + gn->add_child(map); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("c"))); + hbc->add_spacer(); + Label *l=memnew(Label("cmap")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child( l); + gn->add_child(hbc); + + + gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // scalar interpolation (with optional curve) + + case ShaderGraph::NODE_SCALAR_INPUT: { + + gn->set_title("ScalarUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + SpinBox *sb = memnew( SpinBox ); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->scalar_input_node_get_value(type,p_id)); + sb->connect("value_changed",this,"_scalar_input_changed",varray(p_id)); + gn->add_child(sb); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // scalar uniform (assignable in material) + case ShaderGraph::NODE_VEC_INPUT: { + + gn->set_title("VectorUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + Array v3p(true); + for(int i=0;i<3;i++) { + HBoxContainer *hbc = memnew( HBoxContainer ); + Label *l = memnew( Label ); + l->set_text(String::chr('X'+i)); + hbc->add_child(l); + SpinBox *sb = memnew( SpinBox ); + sb->set_h_size_flags(Control::SIZE_EXPAND_FILL); + sb->set_min(-100000); + sb->set_max(100000); + sb->set_step(0.001); + sb->set_val(graph->vec_input_node_get_value(type,p_id)[i]); + sb->connect("value_changed",this,"_vec_input_changed",varray(p_id,v3p)); + v3p.push_back(sb); + hbc->add_child(sb); + gn->add_child(hbc); + } + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + + } break; // vec3 uniform (assignable in material) + case ShaderGraph::NODE_RGB_INPUT: { + + gn->set_title("ColorUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + ColorPickerButton *cpb = memnew( ColorPickerButton ); + cpb->set_color(graph->rgb_input_node_get_value(type,p_id)); + cpb->connect("color_changed",this,"_rgb_input_changed",varray(p_id)); + gn->add_child(cpb); + Label *l = memnew( Label ); + l->set_text("RGB"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(2,false,0,Color(),true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // color uniform (assignable in material) + case ShaderGraph::NODE_XFORM_INPUT: { + gn->set_title("XFUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_xform_input_changed",varray(p_id,edit)); + gn->add_child(edit); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); + + } break; // mat4 uniform (assignable in material) + case ShaderGraph::NODE_TEXTURE_INPUT: { + + gn->set_title("TexUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + TextureFrame *tex = memnew( TextureFrame ); + tex->set_expand(true); + tex->set_custom_minimum_size(Size2(80,80)); + gn->add_child(tex); + tex->set_texture(graph->texture_input_node_get_value(type,p_id)); + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_tex_edited",varray(p_id,edit)); + gn->add_child(edit); + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(3,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(4,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // texture input (assignable in material) + case ShaderGraph::NODE_CUBEMAP_INPUT: { + + gn->set_title("TexUniform"); + LineEdit *le = memnew( LineEdit ); + gn->add_child(le); + le->set_text(graph->input_node_get_name(type,p_id)); + le->connect("text_entered",this,"_input_name_changed",varray(p_id,le)); + + ToolButton *edit = memnew( ToolButton ); + edit->set_text("edit.."); + edit->connect("pressed",this,"_cube_edited",varray(p_id,edit)); + gn->add_child(edit); + + + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(3,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + } break; // cubemap input (assignable in material) + case ShaderGraph::NODE_DEFAULT_TEXTURE: { + + gn->set_title("CanvasItemTex"); + HBoxContainer *hbc = memnew( HBoxContainer ); + hbc->add_constant_override("separation",0); + hbc->add_child( memnew(Label("UV"))); + hbc->add_spacer(); + Label *l=memnew(Label("RGB")); + l->set_align(Label::ALIGN_RIGHT); + hbc->add_child(l); + gn->add_child(hbc); + l = memnew( Label ); + l->set_text("Alpha"); + l->set_align(Label::ALIGN_RIGHT); + gn->add_child(l); + + gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); + gn->set_slot(1,false,0,Color(),true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); + + + } break; // screen texture sampler (takes UV) (only usable in fragment case Shader) + + case ShaderGraph::NODE_OUTPUT: { + gn->set_title("Output"); + gn->set_show_close_button(false); + + List si; + ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); + + int idx=0; + for (List::Element *E=si.front();E;E=E->next()) { + ShaderGraph::SlotInfo& s=E->get(); + if (s.dir==ShaderGraph::SLOT_OUT) { + + Label *l= memnew( Label ); + l->set_text(s.name); + l->set_align(Label::ALIGN_LEFT); + gn->add_child(l); + gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); + idx++; + } + } + + } break; // output (case Shader type dependent) + case ShaderGraph::NODE_COMMENT: { + gn->set_title("Comment"); + TextEdit *te = memnew(TextEdit); + te->set_custom_minimum_size(Size2(100,100)); + gn->add_child(te); + te->set_text(graph->comment_node_get_text(type,p_id)); + te->connect("text_changed",this,"_comment_edited",varray(p_id,te)); + + } break; // comment + + + + } + + gn->connect("dragged",this,"_node_moved",varray(p_id)); + gn->connect("close_request",this,"_node_removed",varray(p_id),CONNECT_DEFERRED); + graph_edit->add_child(gn); + node_map[p_id]=gn; + gn->set_offset(graph->node_get_pos(type,p_id)); } @@ -2056,36 +2056,36 @@ void ShaderGraphView::_create_node(int p_id) { void ShaderGraphView::_update_graph() { - if (block_update) - return; + if (block_update) + return; - for (Map::Element *E=node_map.front();E;E=E->next()) { + for (Map::Element *E=node_map.front();E;E=E->next()) { - memdelete(E->get()); - } + memdelete(E->get()); + } - node_map.clear(); + node_map.clear(); - if (!graph.is_valid()) - return; + if (!graph.is_valid()) + return; - List nl; - graph->get_node_list(type,&nl); + List nl; + graph->get_node_list(type,&nl); - for(List::Element *E=nl.front();E;E=E->next()) { + for(List::Element *E=nl.front();E;E=E->next()) { - _create_node(E->get()); - } - graph_edit->clear_connections(); + _create_node(E->get()); + } + graph_edit->clear_connections(); - List connections; - graph->get_node_connections(type,&connections); - for(List::Element *E=connections.front();E;E=E->next()) { + List connections; + graph->get_node_connections(type,&connections); + for(List::Element *E=connections.front();E;E=E->next()) { - ERR_CONTINUE(!node_map.has(E->get().src_id) || !node_map.has(E->get().dst_id)); - graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot); - } + ERR_CONTINUE(!node_map.has(E->get().src_id) || !node_map.has(E->get().dst_id)); + graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot); + } @@ -2093,314 +2093,314 @@ void ShaderGraphView::_update_graph() { void ShaderGraphView::_sg_updated() { - if (!graph.is_valid()) - return; - switch(graph->get_graph_error(type)) { - case ShaderGraph::GRAPH_OK: status->set_text(""); break; - case ShaderGraph::GRAPH_ERROR_CYCLIC: status->set_text("Error: Cyclic Connection Link"); break; - case ShaderGraph::GRAPH_ERROR_MISSING_CONNECTIONS: status->set_text("Error: Missing Input Connections"); break; - } + if (!graph.is_valid()) + return; + switch(graph->get_graph_error(type)) { + case ShaderGraph::GRAPH_OK: status->set_text(""); break; + case ShaderGraph::GRAPH_ERROR_CYCLIC: status->set_text("Error: Cyclic Connection Link"); break; + case ShaderGraph::GRAPH_ERROR_MISSING_CONNECTIONS: status->set_text("Error: Missing Input Connections"); break; + } } void ShaderGraphView::set_graph(Ref p_graph){ - if (graph.is_valid()) { - graph->disconnect("updated",this,"_sg_updated"); - } - graph=p_graph; - if (graph.is_valid()) { - graph->connect("updated",this,"_sg_updated"); - } - _update_graph(); - _sg_updated(); + if (graph.is_valid()) { + graph->disconnect("updated",this,"_sg_updated"); + } + graph=p_graph; + if (graph.is_valid()) { + graph->connect("updated",this,"_sg_updated"); + } + _update_graph(); + _sg_updated(); } void ShaderGraphView::_notification(int p_what) { - if (p_what==NOTIFICATION_ENTER_TREE) { + if (p_what==NOTIFICATION_ENTER_TREE) { - ped_popup->connect("variant_changed",this,"_variant_edited"); - } - } + ped_popup->connect("variant_changed",this,"_variant_edited"); + } +} void ShaderGraphView::add_node(int p_type, const Vector2 &location) { - List existing; - graph->get_node_list(type,&existing); - existing.sort(); - int newid=1; - for(List::Element *E=existing.front();E;E=E->next()) { - if (!E->next() || (E->get()+1!=E->next()->get())){ - newid=E->get()+1; - break; - } - } - - Vector2 init_ofs = location; - while(true) { - bool valid=true; - for(List::Element *E=existing.front();E;E=E->next()) { - Vector2 pos = graph->node_get_pos(type,E->get()); - if (init_ofs==pos) { - init_ofs+=Vector2(20,20); - valid=false; - break; - - } - } - - if (valid) - break; - } - UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); - ur->create_action("Add Shader Graph Node"); - ur->add_do_method(graph.ptr(),"node_add",type,p_type,newid); - ur->add_do_method(graph.ptr(),"node_set_pos",type,newid,init_ofs); - ur->add_undo_method(graph.ptr(),"node_remove",type,newid); - ur->add_do_method(this,"_update_graph"); - ur->add_undo_method(this,"_update_graph"); - ur->commit_action(); + List existing; + graph->get_node_list(type,&existing); + existing.sort(); + int newid=1; + for(List::Element *E=existing.front();E;E=E->next()) { + if (!E->next() || (E->get()+1!=E->next()->get())){ + newid=E->get()+1; + break; + } + } + + Vector2 init_ofs = location; + while(true) { + bool valid=true; + for(List::Element *E=existing.front();E;E=E->next()) { + Vector2 pos = graph->node_get_pos(type,E->get()); + if (init_ofs==pos) { + init_ofs+=Vector2(20,20); + valid=false; + break; + + } + } + + if (valid) + break; + } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Add Shader Graph Node"); + ur->add_do_method(graph.ptr(),"node_add",type,p_type,newid); + ur->add_do_method(graph.ptr(),"node_set_pos",type,newid,init_ofs); + ur->add_undo_method(graph.ptr(),"node_remove",type,newid); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); } void ShaderGraphView::_bind_methods() { - ObjectTypeDB::bind_method("_update_graph",&ShaderGraphView::_update_graph); - ObjectTypeDB::bind_method("_begin_node_move", &ShaderGraphView::_begin_node_move); - ObjectTypeDB::bind_method("_node_moved",&ShaderGraphView::_node_moved); - ObjectTypeDB::bind_method("_end_node_move", &ShaderGraphView::_end_node_move); - ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node); - ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed); - ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request); - ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); - - ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); - ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); - ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed); - ObjectTypeDB::bind_method("_xform_const_changed",&ShaderGraphView::_xform_const_changed); - ObjectTypeDB::bind_method("_scalar_op_changed",&ShaderGraphView::_scalar_op_changed); - ObjectTypeDB::bind_method("_vec_op_changed",&ShaderGraphView::_vec_op_changed); - ObjectTypeDB::bind_method("_vec_scalar_op_changed",&ShaderGraphView::_vec_scalar_op_changed); - ObjectTypeDB::bind_method("_rgb_op_changed",&ShaderGraphView::_rgb_op_changed); - ObjectTypeDB::bind_method("_xform_inv_rev_changed",&ShaderGraphView::_xform_inv_rev_changed); - ObjectTypeDB::bind_method("_scalar_func_changed",&ShaderGraphView::_scalar_func_changed); - ObjectTypeDB::bind_method("_vec_func_changed",&ShaderGraphView::_vec_func_changed); - ObjectTypeDB::bind_method("_scalar_input_changed",&ShaderGraphView::_scalar_input_changed); - ObjectTypeDB::bind_method("_vec_input_changed",&ShaderGraphView::_vec_input_changed); - ObjectTypeDB::bind_method("_xform_input_changed",&ShaderGraphView::_xform_input_changed); - ObjectTypeDB::bind_method("_rgb_input_changed",&ShaderGraphView::_rgb_input_changed); - ObjectTypeDB::bind_method("_tex_input_change",&ShaderGraphView::_tex_input_change); - ObjectTypeDB::bind_method("_cube_input_change",&ShaderGraphView::_cube_input_change); - ObjectTypeDB::bind_method("_input_name_changed",&ShaderGraphView::_input_name_changed); - ObjectTypeDB::bind_method("_tex_edited",&ShaderGraphView::_tex_edited); - ObjectTypeDB::bind_method("_variant_edited",&ShaderGraphView::_variant_edited); - ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited); - ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited); - ObjectTypeDB::bind_method("_color_ramp_changed",&ShaderGraphView::_color_ramp_changed); - ObjectTypeDB::bind_method("_curve_changed",&ShaderGraphView::_curve_changed); - - ObjectTypeDB::bind_method("_sg_updated",&ShaderGraphView::_sg_updated); + ObjectTypeDB::bind_method("_update_graph",&ShaderGraphView::_update_graph); + ObjectTypeDB::bind_method("_begin_node_move", &ShaderGraphView::_begin_node_move); + ObjectTypeDB::bind_method("_node_moved",&ShaderGraphView::_node_moved); + ObjectTypeDB::bind_method("_end_node_move", &ShaderGraphView::_end_node_move); + ObjectTypeDB::bind_method("_move_node",&ShaderGraphView::_move_node); + ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed); + ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request); + ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); + + ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); + ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); + ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed); + ObjectTypeDB::bind_method("_xform_const_changed",&ShaderGraphView::_xform_const_changed); + ObjectTypeDB::bind_method("_scalar_op_changed",&ShaderGraphView::_scalar_op_changed); + ObjectTypeDB::bind_method("_vec_op_changed",&ShaderGraphView::_vec_op_changed); + ObjectTypeDB::bind_method("_vec_scalar_op_changed",&ShaderGraphView::_vec_scalar_op_changed); + ObjectTypeDB::bind_method("_rgb_op_changed",&ShaderGraphView::_rgb_op_changed); + ObjectTypeDB::bind_method("_xform_inv_rev_changed",&ShaderGraphView::_xform_inv_rev_changed); + ObjectTypeDB::bind_method("_scalar_func_changed",&ShaderGraphView::_scalar_func_changed); + ObjectTypeDB::bind_method("_vec_func_changed",&ShaderGraphView::_vec_func_changed); + ObjectTypeDB::bind_method("_scalar_input_changed",&ShaderGraphView::_scalar_input_changed); + ObjectTypeDB::bind_method("_vec_input_changed",&ShaderGraphView::_vec_input_changed); + ObjectTypeDB::bind_method("_xform_input_changed",&ShaderGraphView::_xform_input_changed); + ObjectTypeDB::bind_method("_rgb_input_changed",&ShaderGraphView::_rgb_input_changed); + ObjectTypeDB::bind_method("_tex_input_change",&ShaderGraphView::_tex_input_change); + ObjectTypeDB::bind_method("_cube_input_change",&ShaderGraphView::_cube_input_change); + ObjectTypeDB::bind_method("_input_name_changed",&ShaderGraphView::_input_name_changed); + ObjectTypeDB::bind_method("_tex_edited",&ShaderGraphView::_tex_edited); + ObjectTypeDB::bind_method("_variant_edited",&ShaderGraphView::_variant_edited); + ObjectTypeDB::bind_method("_cube_edited",&ShaderGraphView::_cube_edited); + ObjectTypeDB::bind_method("_comment_edited",&ShaderGraphView::_comment_edited); + ObjectTypeDB::bind_method("_color_ramp_changed",&ShaderGraphView::_color_ramp_changed); + ObjectTypeDB::bind_method("_curve_changed",&ShaderGraphView::_curve_changed); + + ObjectTypeDB::bind_method("_sg_updated",&ShaderGraphView::_sg_updated); } ShaderGraphView::ShaderGraphView(ShaderGraph::ShaderType p_type) { - type=p_type; - graph_edit = memnew( GraphEdit ); - block_update=false; - ped_popup = memnew( CustomPropertyEditor ); - graph_edit->add_child(ped_popup); - status = memnew( Label ); - graph_edit->get_top_layer()->add_child(status); - graph_edit->connect("_begin_node_move", this, "_begin_node_move"); - graph_edit->connect("_end_node_move", this, "_end_node_move"); - status->set_pos(Vector2(5,5)); - status->add_color_override("font_color_shadow",Color(0,0,0)); - status->add_color_override("font_color",Color(1,0.4,0.3)); - status->add_constant_override("shadow_as_outline",1); - status->add_constant_override("shadow_offset_x",2); - status->add_constant_override("shadow_offset_y",2); - status->set_text(""); + type=p_type; + graph_edit = memnew( GraphEdit ); + block_update=false; + ped_popup = memnew( CustomPropertyEditor ); + graph_edit->add_child(ped_popup); + status = memnew( Label ); + graph_edit->get_top_layer()->add_child(status); + graph_edit->connect("_begin_node_move", this, "_begin_node_move"); + graph_edit->connect("_end_node_move", this, "_end_node_move"); + status->set_pos(Vector2(5,5)); + status->add_color_override("font_color_shadow",Color(0,0,0)); + status->add_color_override("font_color",Color(1,0.4,0.3)); + status->add_constant_override("shadow_as_outline",1); + status->add_constant_override("shadow_offset_x",2); + status->add_constant_override("shadow_offset_y",2); + status->set_text(""); } //////////////edit////////////// void ShaderGraphEditor::edit(Ref p_shader) { - for(int i=0;iset_graph(p_shader); - } + for(int i=0;iset_graph(p_shader); + } } void ShaderGraphEditor::_add_node(int p_type) { - ShaderGraph::ShaderType shader_type=ShaderGraph::ShaderType(tabs->get_current_tab()); + ShaderGraph::ShaderType shader_type=ShaderGraph::ShaderType(tabs->get_current_tab()); - graph_edits[shader_type]->add_node(p_type, next_location); + graph_edits[shader_type]->add_node(p_type, next_location); } void ShaderGraphEditor::_popup_requested(const Vector2 &p_position) { - next_location = get_local_mouse_pos(); - popup->set_global_pos(p_position); - popup->set_size( Size2( 200, 0) ); - popup->popup(); - popup->call_deferred("grab_click_focus"); - popup->set_invalidate_click_until_motion(); + next_location = get_local_mouse_pos(); + popup->set_global_pos(p_position); + popup->set_size( Size2( 200, 0) ); + popup->popup(); + popup->call_deferred("grab_click_focus"); + popup->set_invalidate_click_until_motion(); } void ShaderGraphEditor::_notification(int p_what) { - if (p_what==NOTIFICATION_ENTER_TREE) { + if (p_what==NOTIFICATION_ENTER_TREE) { - for(int i=0;iadd_icon_item(get_icon(ic,"EditorIcons"),v,i); - if (addsep) - popup->add_separator(); - } - popup->connect("item_pressed",this,"_add_node"); + String nn = node_names[i]; + String ic = nn.get_slice(":",0); + String v = nn.get_slice(":",1); + bool addsep=false; + if (nn.ends_with(":")) { + addsep=true; + } + popup->add_icon_item(get_icon(ic,"EditorIcons"),v,i); + if (addsep) + popup->add_separator(); + } + popup->connect("item_pressed",this,"_add_node"); - } + } } void ShaderGraphEditor::_bind_methods() { - ObjectTypeDB::bind_method("_add_node",&ShaderGraphEditor::_add_node); - ObjectTypeDB::bind_method("_popup_requested",&ShaderGraphEditor::_popup_requested); + ObjectTypeDB::bind_method("_add_node",&ShaderGraphEditor::_add_node); + ObjectTypeDB::bind_method("_popup_requested",&ShaderGraphEditor::_popup_requested); } const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={ - "GraphInput:Input", // all inputs (shader type dependent) - "GraphScalar:Scalar Constant", //scalar constant - "GraphVector:Vector Constant", //vec3 constant - "GraphRgb:RGB Constant", //rgb constant (shows a color picker instead) - "GraphXform:XForm Constant", // 4x4 matrix constant - "GraphTime:Time:", // time in seconds - "GraphTexscreen:Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader) - "GraphScalarOp:Scalar Operator", // scalar vs scalar op (mul", add", div", etc) - "GraphVecOp:Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc) - "GraphVecScalarOp:Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc) - "GraphRgbOp:RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc. - "GraphXformMult:XForm Multiply", // mat4 x mat4 - "GraphXformVecMult:XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option) - "GraphXformVecImult:Form+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option) - "GraphXformScalarFunc:Scalar Function", // scalar function (sin", cos", etc) - "GraphXformVecFunc:Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc) - "GraphVecLength:Vector Length", // vec3 length - "GraphVecDp:Dot Product:", // vec3 . vec3 (dot product -> scalar output) - "GraphVecToScalars:Vector -> Scalars", // 1 vec3 input", 3 scalar outputs - "GraphScalarsToVec:Scalars -> Vector", // 3 scalar input", 1 vec3 output - "GraphXformToVecs:XForm -> Vectors", // 3 vec input", 1 xform output - "GraphVecsToXform:Vectors -> XForm:", // 3 vec input", 1 xform output - "GraphScalarInterp:Scalar Interpolate", // scalar interpolation (with optional curve) - "GraphVecInterp:Vector Interpolate:", // vec3 interpolation (with optional curve) - "GraphColorRamp:Color Ramp", // vec3 interpolation (with optional curve) - "GraphCurveMap:Curve Remap:", // vec3 interpolation (with optional curve) - "GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material) - "GraphVectorUniform:Vector Uniform", // vec3 uniform (assignable in material) - "GraphRgbUniform:RGB Uniform", // color uniform (assignable in material) - "GraphXformUniform:XForm Uniform", // mat4 uniform (assignable in material) - "GraphTextureUniform:Texture Uniform", // texture input (assignable in material) - "GraphCubeUniform:CubeMap Uniform:", // cubemap input (assignable in material) - "GraphDefaultTexture:CanvasItem Texture:", // cubemap input (assignable in material) - "Output", // output (shader type dependent) - "GraphComment:Comment", // comment + "GraphInput:Input", // all inputs (shader type dependent) + "GraphScalar:Scalar Constant", //scalar constant + "GraphVector:Vector Constant", //vec3 constant + "GraphRgb:RGB Constant", //rgb constant (shows a color picker instead) + "GraphXform:XForm Constant", // 4x4 matrix constant + "GraphTime:Time:", // time in seconds + "GraphTexscreen:Screen Sample", // screen texture sampler (takes uv) (only usable in fragment shader) + "GraphScalarOp:Scalar Operator", // scalar vs scalar op (mul", add", div", etc) + "GraphVecOp:Vector Operator", // vec3 vs vec3 op (mul",ad",div",crossprod",etc) + "GraphVecScalarOp:Scalar+Vector Operator", // vec3 vs scalar op (mul", add", div", etc) + "GraphRgbOp:RGB Operator:", // vec3 vs vec3 rgb op (with scalar amount)", like brighten", darken", burn", dodge", multiply", etc. + "GraphXformMult:XForm Multiply", // mat4 x mat4 + "GraphXformVecMult:XForm+Vector Multiply", // mat4 x vec3 mult (with no-translation option) + "GraphXformVecImult:Form+Vector InvMultiply:", // mat4 x vec3 inverse mult (with no-translation option) + "GraphXformScalarFunc:Scalar Function", // scalar function (sin", cos", etc) + "GraphXformVecFunc:Vector Function", // vector function (normalize", negate", reciprocal", rgb2hsv", hsv2rgb", etc", etc) + "GraphVecLength:Vector Length", // vec3 length + "GraphVecDp:Dot Product:", // vec3 . vec3 (dot product -> scalar output) + "GraphVecToScalars:Vector -> Scalars", // 1 vec3 input", 3 scalar outputs + "GraphScalarsToVec:Scalars -> Vector", // 3 scalar input", 1 vec3 output + "GraphXformToVecs:XForm -> Vectors", // 3 vec input", 1 xform output + "GraphVecsToXform:Vectors -> XForm:", // 3 vec input", 1 xform output + "GraphScalarInterp:Scalar Interpolate", // scalar interpolation (with optional curve) + "GraphVecInterp:Vector Interpolate:", // vec3 interpolation (with optional curve) + "GraphColorRamp:Color Ramp", // vec3 interpolation (with optional curve) + "GraphCurveMap:Curve Remap:", // vec3 interpolation (with optional curve) + "GraphScalarUniform:Scalar Uniform", // scalar uniform (assignable in material) + "GraphVectorUniform:Vector Uniform", // vec3 uniform (assignable in material) + "GraphRgbUniform:RGB Uniform", // color uniform (assignable in material) + "GraphXformUniform:XForm Uniform", // mat4 uniform (assignable in material) + "GraphTextureUniform:Texture Uniform", // texture input (assignable in material) + "GraphCubeUniform:CubeMap Uniform:", // cubemap input (assignable in material) + "GraphDefaultTexture:CanvasItem Texture:", // cubemap input (assignable in material) + "Output", // output (shader type dependent) + "GraphComment:Comment", // comment }; ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { - _2d=p_2d; + _2d=p_2d; - HBoxContainer *hbc = memnew( HBoxContainer ); - popup = memnew( PopupMenu ); - hbc->add_child(popup); - add_child(hbc); + HBoxContainer *hbc = memnew( HBoxContainer ); + popup = memnew( PopupMenu ); + hbc->add_child(popup); + add_child(hbc); - tabs = memnew(TabContainer); - tabs->set_v_size_flags(SIZE_EXPAND_FILL); - add_child(tabs); - const char* sname[ShaderGraph::SHADER_TYPE_MAX]={ - "Vertex", - "Fragment", - "Light" - }; - for(int i=0;iset_v_size_flags(SIZE_EXPAND_FILL); + add_child(tabs); + const char* sname[ShaderGraph::SHADER_TYPE_MAX]={ + "Vertex", + "Fragment", + "Light" + }; + for(int i=0;iget_graph_edit()->set_name(sname[i]); - tabs->add_child(graph_edits[i]->get_graph_edit()); - graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); - graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); - graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); - graph_edits[i]->get_graph_edit()->set_right_disconnects(true); - } + graph_edits[i]= memnew( ShaderGraphView(ShaderGraph::ShaderType(i)) ); + add_child(graph_edits[i]); + graph_edits[i]->get_graph_edit()->set_name(sname[i]); + tabs->add_child(graph_edits[i]->get_graph_edit()); + graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); + graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); + graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); + graph_edits[i]->get_graph_edit()->set_right_disconnects(true); + } - tabs->set_current_tab(1); + tabs->set_current_tab(1); - set_custom_minimum_size(Size2(100,300)); + set_custom_minimum_size(Size2(100,300)); } void ShaderGraphEditorPlugin::edit(Object *p_object) { - shader_editor->edit(p_object->cast_to()); + shader_editor->edit(p_object->cast_to()); } bool ShaderGraphEditorPlugin::handles(Object *p_object) const { - ShaderGraph *shader=p_object->cast_to(); - if (!shader) - return false; - if (_2d) - return shader->get_mode()==Shader::MODE_CANVAS_ITEM; - else - return shader->get_mode()==Shader::MODE_MATERIAL; + ShaderGraph *shader=p_object->cast_to(); + if (!shader) + return false; + if (_2d) + return shader->get_mode()==Shader::MODE_CANVAS_ITEM; + else + return shader->get_mode()==Shader::MODE_MATERIAL; } void ShaderGraphEditorPlugin::make_visible(bool p_visible) { - if (p_visible) { - shader_editor->show(); - } else { + if (p_visible) { + shader_editor->show(); + } else { - shader_editor->hide(); - } + shader_editor->hide(); + } } ShaderGraphEditorPlugin::ShaderGraphEditorPlugin(EditorNode *p_node, bool p_2d) { - _2d=p_2d; - editor=p_node; - shader_editor = memnew( ShaderGraphEditor(p_2d) ); - shader_editor->hide(); - if (p_2d) - CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(shader_editor); - else - SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); + _2d=p_2d; + editor=p_node; + shader_editor = memnew( ShaderGraphEditor(p_2d) ); + shader_editor->hide(); + if (p_2d) + CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(shader_editor); + else + SpatialEditor::get_singleton()->get_shader_split()->add_child(shader_editor); -// editor->get_viewport()->add_child(shader_editor); -// shader_editor->set_area_as_parent_rect(); -// shader_editor->hide(); + // editor->get_viewport()->add_child(shader_editor); + // shader_editor->set_area_as_parent_rect(); + // shader_editor->hide(); } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index ea21a7706f..5f93b9df7d 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -41,189 +41,189 @@ #include "tools/editor/property_editor.h" #include "scene/resources/shader_graph.h" /** - @author Juan Linietsky + @author Juan Linietsky */ class GraphColorRampEdit : public Control { - OBJ_TYPE(GraphColorRampEdit,Control); + OBJ_TYPE(GraphColorRampEdit,Control); - struct Point { + struct Point { - float offset; - Color color; - bool operator<(const Point& p_ponit) const { - return offset points; + bool grabbing; + int grabbed; + float grabbed_at; + Vector points; - void _color_changed(const Color& p_color); + void _color_changed(const Color& p_color); protected: - void _input_event(const InputEvent& p_event); - void _notification(int p_what); - static void _bind_methods(); + void _input_event(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); public: - void set_ramp(const Vector& p_offsets,const Vector& p_colors); - Vector get_offsets() const; - Vector get_colors() const; - virtual Size2 get_minimum_size() const; - GraphColorRampEdit(); + void set_ramp(const Vector& p_offsets,const Vector& p_colors); + Vector get_offsets() const; + Vector get_colors() const; + virtual Size2 get_minimum_size() const; + GraphColorRampEdit(); }; class GraphCurveMapEdit : public Control { - OBJ_TYPE(GraphCurveMapEdit,Control); + OBJ_TYPE(GraphCurveMapEdit,Control); - struct Point { + struct Point { - float offset; - float height; - bool operator<(const Point& p_ponit) const { - return offset points; + bool grabbing; + int grabbed; + Vector points; - void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); + void _plot_curve(const Vector2& p_a,const Vector2& p_b,const Vector2& p_c,const Vector2& p_d); protected: - void _input_event(const InputEvent& p_event); - void _notification(int p_what); - static void _bind_methods(); + void _input_event(const InputEvent& p_event); + void _notification(int p_what); + static void _bind_methods(); public: - void set_points(const Vector& p_points); - Vector get_points() const; - virtual Size2 get_minimum_size() const; - GraphCurveMapEdit(); + void set_points(const Vector& p_points); + Vector get_points() const; + virtual Size2 get_minimum_size() const; + GraphCurveMapEdit(); }; class ShaderGraphView : public Node { - OBJ_TYPE(ShaderGraphView,Node); - - - - CustomPropertyEditor *ped_popup; - bool block_update; - - Label *status; - GraphEdit *graph_edit; - Ref graph; - int edited_id; - - ShaderGraph::ShaderType type; - - void _update_graph(); - void _create_node(int p_id); - - - - void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); - void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); - - void _node_removed(int p_id); - void _begin_node_move(); - void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); - void _end_node_move(); - void _move_node(int p_id,const Vector2& p_to); - - void _scalar_const_changed(double p_value,int p_id); - void _vec_const_changed(double p_value, int p_id, Array p_arr); - void _rgb_const_changed(const Color& p_color, int p_id); - void _xform_const_changed(int p_id,Node* p_button); - void _scalar_op_changed(int p_op, int p_id); - void _vec_op_changed(int p_op, int p_id); - void _vec_scalar_op_changed(int p_op, int p_id); - void _rgb_op_changed(int p_op, int p_id); - void _xform_inv_rev_changed(bool p_enabled, int p_id); - void _scalar_func_changed(int p_func, int p_id); - void _vec_func_changed(int p_func, int p_id); - void _scalar_input_changed(double p_value,int p_id); - void _vec_input_changed(double p_value, int p_id, Array p_arr); - void _xform_input_changed(int p_id,Node* p_button); - void _rgb_input_changed(const Color& p_color, int p_id); - void _tex_input_change(int p_id,Node* p_button); - void _cube_input_change(int p_id); - void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit); - void _tex_edited(int p_id,Node* p_button); - void _cube_edited(int p_id,Node* p_button); - void _variant_edited(); - void _comment_edited(int p_id,Node* p_button); - void _color_ramp_changed(int p_id,Node* p_ramp); - void _curve_changed(int p_id,Node* p_curve); - void _sg_updated(); - Map node_map; + OBJ_TYPE(ShaderGraphView,Node); + + + + CustomPropertyEditor *ped_popup; + bool block_update; + + Label *status; + GraphEdit *graph_edit; + Ref graph; + int edited_id; + + ShaderGraph::ShaderType type; + + void _update_graph(); + void _create_node(int p_id); + + + + void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); + + void _node_removed(int p_id); + void _begin_node_move(); + void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); + void _end_node_move(); + void _move_node(int p_id,const Vector2& p_to); + + void _scalar_const_changed(double p_value,int p_id); + void _vec_const_changed(double p_value, int p_id, Array p_arr); + void _rgb_const_changed(const Color& p_color, int p_id); + void _xform_const_changed(int p_id,Node* p_button); + void _scalar_op_changed(int p_op, int p_id); + void _vec_op_changed(int p_op, int p_id); + void _vec_scalar_op_changed(int p_op, int p_id); + void _rgb_op_changed(int p_op, int p_id); + void _xform_inv_rev_changed(bool p_enabled, int p_id); + void _scalar_func_changed(int p_func, int p_id); + void _vec_func_changed(int p_func, int p_id); + void _scalar_input_changed(double p_value,int p_id); + void _vec_input_changed(double p_value, int p_id, Array p_arr); + void _xform_input_changed(int p_id,Node* p_button); + void _rgb_input_changed(const Color& p_color, int p_id); + void _tex_input_change(int p_id,Node* p_button); + void _cube_input_change(int p_id); + void _input_name_changed(const String& p_name,int p_id,Node* p_line_edit); + void _tex_edited(int p_id,Node* p_button); + void _cube_edited(int p_id,Node* p_button); + void _variant_edited(); + void _comment_edited(int p_id,Node* p_button); + void _color_ramp_changed(int p_id,Node* p_ramp); + void _curve_changed(int p_id,Node* p_curve); + void _sg_updated(); + Map node_map; protected: - void _notification(int p_what); - static void _bind_methods(); + void _notification(int p_what); + static void _bind_methods(); public: - void add_node(int p_type, const Vector2 &location); - GraphEdit *get_graph_edit() { return graph_edit; } - void set_graph(Ref p_graph); + void add_node(int p_type, const Vector2 &location); + GraphEdit *get_graph_edit() { return graph_edit; } + void set_graph(Ref p_graph); - ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT); + ShaderGraphView(ShaderGraph::ShaderType p_type=ShaderGraph::SHADER_TYPE_FRAGMENT); }; class ShaderGraphEditor : public VBoxContainer { - OBJ_TYPE(ShaderGraphEditor,VBoxContainer); + OBJ_TYPE(ShaderGraphEditor,VBoxContainer); - PopupMenu *popup; - TabContainer *tabs; - ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; - static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; - Vector2 next_location; + PopupMenu *popup; + TabContainer *tabs; + ShaderGraphView *graph_edits[ShaderGraph::SHADER_TYPE_MAX]; + static const char* node_names[ShaderGraph::NODE_TYPE_MAX]; + Vector2 next_location; - bool _2d; - void _add_node(int p_type); - void _popup_requested(const Vector2 &p_position); + bool _2d; + void _add_node(int p_type); + void _popup_requested(const Vector2 &p_position); protected: - void _notification(int p_what); - static void _bind_methods(); + void _notification(int p_what); + static void _bind_methods(); public: - void edit(Ref p_shader); - ShaderGraphEditor(bool p_2d); + void edit(Ref p_shader); + ShaderGraphEditor(bool p_2d); }; class ShaderGraphEditorPlugin : public EditorPlugin { - OBJ_TYPE( ShaderGraphEditorPlugin, EditorPlugin ); + OBJ_TYPE( ShaderGraphEditorPlugin, EditorPlugin ); - bool _2d; - ShaderGraphEditor *shader_editor; - EditorNode *editor; + bool _2d; + ShaderGraphEditor *shader_editor; + EditorNode *editor; public: - virtual String get_name() const { return "ShaderGraph"; } - 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); + virtual String get_name() const { return "ShaderGraph"; } + 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); - ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); - ~ShaderGraphEditorPlugin(); + ShaderGraphEditorPlugin(EditorNode *p_node,bool p_2d); + ~ShaderGraphEditorPlugin(); }; #endif -- cgit v1.2.3 From bdde79a3f433dbff244e544b72ac8946d8d9b44b Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Fri, 24 Jul 2015 21:59:48 -0300 Subject: Box selection for GraphNodes --- scene/gui/graph_edit.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++----- scene/gui/graph_edit.h | 7 ++++ 2 files changed, 90 insertions(+), 8 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 22a03504c6..003486dcf1 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -169,7 +169,6 @@ void GraphEdit::remove_child_notify(Node *p_child) { void GraphEdit::_notification(int p_what) { if (p_what==NOTIFICATION_READY) { - Size2 size = top_layer->get_size(); Size2 hmin = h_scroll->get_combined_minimum_size(); Size2 vmin = v_scroll->get_combined_minimum_size(); @@ -488,7 +487,8 @@ void GraphEdit::_top_layer_draw() { connections.erase(to_erase.front()->get()); to_erase.pop_front(); } - //draw connections + if (box_selecting) + top_layer->draw_rect(box_selecting_rect,Color(0.7,0.7,1.0,0.3)); } void GraphEdit::_input_event(const InputEvent& p_ev) { @@ -509,13 +509,51 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { } } + if (p_ev.type==InputEvent::MOUSE_MOTION && box_selecting) { + box_selecting_to = get_local_mouse_pos(); + + box_selecting_rect = Rect2(MIN(box_selecting_from.x,box_selecting_to.x), + MIN(box_selecting_from.y,box_selecting_to.y), + ABS(box_selecting_from.x-box_selecting_to.x), + ABS(box_selecting_from.y-box_selecting_to.y)); + + for(int i=get_child_count()-1;i>=0;i--) { + + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; + + bool in_box = gn->get_rect().intersects(box_selecting_rect); + + if (in_box) + gn->set_selected(box_selection_mode_aditive); + else + gn->set_selected(previus_selected.find(gn)!=NULL); + } + + top_layer->update(); + } + if (p_ev.type== InputEvent::MOUSE_BUTTON) { const InputEventMouseButton &b=p_ev.mouse_button; if (b.button_index==BUTTON_RIGHT && b.pressed) { - emit_signal("popup_request", Vector2(b.global_x, b.global_y)); + if (box_selecting) { + box_selecting = false; + for(int i=get_child_count()-1;i>=0;i--) { + + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; + + gn->set_selected(previus_selected.find(gn)!=NULL); + } + top_layer->update(); + } else { + emit_signal("popup_request", Vector2(b.global_x, b.global_y)); + } } if (b.button_index==BUTTON_LEFT && !b.pressed && dragging) { @@ -584,16 +622,50 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { } } else { - for(int i=get_child_count()-1;i>=0;i--) { + box_selecting = true; + box_selecting_from = get_local_mouse_pos(); + if (b.mod.control) { + box_selection_mode_aditive = true; + previus_selected.clear(); + for(int i=get_child_count()-1;i>=0;i--) { + + GraphNode *gn=get_child(i)->cast_to(); + if (!gn || !gn->is_selected()) + continue; + + previus_selected.push_back(gn); + } + } else if (b.mod.shift) { + box_selection_mode_aditive = false; + previus_selected.clear(); + for(int i=get_child_count()-1;i>=0;i--) { - GraphNode *gn=get_child(i)->cast_to(); - if (!gn) - continue; + GraphNode *gn=get_child(i)->cast_to(); + if (!gn || !gn->is_selected()) + continue; - gn->set_selected(false); + previus_selected.push_back(gn); + } + } else { + box_selection_mode_aditive = true; + previus_selected.clear(); + for(int i=get_child_count()-1;i>=0;i--) { + + GraphNode *gn=get_child(i)->cast_to(); + if (!gn) + continue; + + gn->set_selected(false); + } } } } + + if (b.button_index==BUTTON_LEFT && !b.pressed && box_selecting) { + box_selecting = false; + previus_selected.clear(); + top_layer->update(); + } } } @@ -678,6 +750,9 @@ GraphEdit::GraphEdit() { connecting=false; right_disconnects=false; + box_selecting = false; + dragging = false; + h_scroll->connect("value_changed", this,"_scroll_moved"); v_scroll->connect("value_changed", this,"_scroll_moved"); } diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h index 5ab0f3300e..44f5a369c2 100644 --- a/scene/gui/graph_edit.h +++ b/scene/gui/graph_edit.h @@ -53,6 +53,13 @@ private: bool just_selected; Vector2 drag_accum; + bool box_selecting; + bool box_selection_mode_aditive; + Point2 box_selecting_from; + Point2 box_selecting_to; + Rect2 box_selecting_rect; + List previus_selected; + bool right_disconnects; bool updating; List connections; -- cgit v1.2.3 From f5bfd497aab7e24a6f4dc0315e9e9333504067a0 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Sun, 26 Jul 2015 02:18:32 +0300 Subject: Haiku: add sound support --- drivers/SCsub | 1 + drivers/media_kit/SCsub | 5 + drivers/media_kit/audio_driver_media_kit.cpp | 143 +++++++++++++++++++++++++++ drivers/media_kit/audio_driver_media_kit.h | 72 ++++++++++++++ platform/haiku/detect.py | 5 +- platform/haiku/os_haiku.cpp | 4 +- platform/haiku/os_haiku.h | 6 +- 7 files changed, 230 insertions(+), 6 deletions(-) create mode 100644 drivers/media_kit/SCsub create mode 100644 drivers/media_kit/audio_driver_media_kit.cpp create mode 100644 drivers/media_kit/audio_driver_media_kit.h diff --git a/drivers/SCsub b/drivers/SCsub index 6ab0973625..2bb2d4966c 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -12,6 +12,7 @@ SConscript('windows/SCsub'); SConscript('gles2/SCsub'); SConscript('gl_context/SCsub'); SConscript('openssl/SCsub'); +SConscript('media_kit/SCsub'); if (env["png"]=="yes"): SConscript("png/SCsub"); diff --git a/drivers/media_kit/SCsub b/drivers/media_kit/SCsub new file mode 100644 index 0000000000..9fbb467baa --- /dev/null +++ b/drivers/media_kit/SCsub @@ -0,0 +1,5 @@ +Import('env') + +env.add_source_files(env.drivers_sources,"*.cpp") + +Export('env') diff --git a/drivers/media_kit/audio_driver_media_kit.cpp b/drivers/media_kit/audio_driver_media_kit.cpp new file mode 100644 index 0000000000..3fabe4f96f --- /dev/null +++ b/drivers/media_kit/audio_driver_media_kit.cpp @@ -0,0 +1,143 @@ +/*************************************************************************/ +/* audio_driver_media_kit.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "audio_driver_media_kit.h" + +#ifdef MEDIA_KIT_ENABLED + +#include "globals.h" + +int32_t* AudioDriverMediaKit::samples_in = NULL; + +Error AudioDriverMediaKit::init() { + active = false; + + mix_rate = 44100; + output_format = OUTPUT_STEREO; + channels = 2; + + int latency = GLOBAL_DEF("audio/output_latency", 25); + buffer_size = nearest_power_of_2(latency * mix_rate / 1000); + samples_in = memnew_arr(int32_t, buffer_size * channels); + + media_raw_audio_format format; + format = media_raw_audio_format::wildcard; + format.frame_rate = mix_rate; + format.channel_count = channels; + format.format = media_raw_audio_format::B_AUDIO_INT; + format.byte_order = B_MEDIA_LITTLE_ENDIAN; + format.buffer_size = buffer_size * sizeof(int32_t) * channels; + + player = new BSoundPlayer( + &format, + "godot_sound_server", + AudioDriverMediaKit::PlayBuffer, + NULL, + this + ); + + if (player->InitCheck() != B_OK) { + fprintf(stderr, "MediaKit ERR: can not create a BSoundPlayer instance\n"); + ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN); + } + + mutex = Mutex::create(); + player->Start(); + + return OK; +} + +void AudioDriverMediaKit::PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format) { + AudioDriverMediaKit* ad = (AudioDriverMediaKit*) cookie; + int32_t* buf = (int32_t*) buffer; + + if (!ad->active) { + for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { + AudioDriverMediaKit::samples_in[i] = 0; + } + } else { + ad->lock(); + ad->audio_server_process(ad->buffer_size, AudioDriverMediaKit::samples_in); + ad->unlock(); + } + + for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { + buf[i] = AudioDriverMediaKit::samples_in[i]; + } +} + +void AudioDriverMediaKit::start() { + active = true; +} + +int AudioDriverMediaKit::get_mix_rate() const { + return mix_rate; +} + +AudioDriverSW::OutputFormat AudioDriverMediaKit::get_output_format() const { + return output_format; +} + +void AudioDriverMediaKit::lock() { + if (!mutex) + return; + + mutex->lock(); +} + +void AudioDriverMediaKit::unlock() { + if (!mutex) + return; + + mutex->unlock(); +} + +void AudioDriverMediaKit::finish() { + if (player) + delete player; + + if (samples_in) { + memdelete_arr(samples_in); + }; + + if (mutex) { + memdelete(mutex); + mutex = NULL; + } +} + +AudioDriverMediaKit::AudioDriverMediaKit() { + mutex = NULL; + player = NULL; +} + +AudioDriverMediaKit::~AudioDriverMediaKit() { + +} + +#endif diff --git a/drivers/media_kit/audio_driver_media_kit.h b/drivers/media_kit/audio_driver_media_kit.h new file mode 100644 index 0000000000..a23ec447f1 --- /dev/null +++ b/drivers/media_kit/audio_driver_media_kit.h @@ -0,0 +1,72 @@ +/*************************************************************************/ +/* audio_driver_media_kit.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "servers/audio/audio_server_sw.h" + +#ifdef MEDIA_KIT_ENABLED + +#include "core/os/thread.h" +#include "core/os/mutex.h" + +#include // needed for image_id +#include + +class AudioDriverMediaKit : public AudioDriverSW { + Mutex* mutex; + + BSoundPlayer* player; + static int32_t* samples_in; + + static void PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format); + + unsigned int mix_rate; + OutputFormat output_format; + unsigned int buffer_size; + int channels; + + bool active; + +public: + + const char* get_name() const { + return "MediaKit"; + }; + + virtual Error init(); + virtual void start(); + virtual int get_mix_rate() const; + virtual OutputFormat get_output_format() const; + virtual void lock(); + virtual void unlock(); + virtual void finish(); + + AudioDriverMediaKit(); + ~AudioDriverMediaKit(); +}; + +#endif diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index d219850bb4..f4198e50cd 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -52,10 +52,9 @@ def configure(env): env.Append(CCFLAGS=['-g2', '-Wall','-DDEBUG_ENABLED','-DDEBUG_MEMORY_ENABLED']) #env.Append(CCFLAGS=['-DFREETYPE_ENABLED']) - env.Append(CPPFLAGS = ['-DGLEW_ENABLED']) - env.Append(CPPFLAGS = ['-DOPENGL_ENABLED']) + env.Append(CPPFLAGS = ['-DGLEW_ENABLED', '-DOPENGL_ENABLED', '-DMEDIA_KIT_ENABLED']) env.Append(CPPFLAGS = ['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL']) - env.Append(LIBS = ['be', 'game', 'GL', 'GLEW', 'z', 'network', 'bnetapi']) + env.Append(LIBS = ['be', 'game', 'media', 'network', 'bnetapi', 'z', 'GL', 'GLEW']) import methods env.Append(BUILDERS = {'GLSL120' : env.Builder(action = methods.build_legacygl_headers, suffix = 'glsl.h',src_suffix = '.glsl')}) diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 2c29260281..1edb23d504 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -11,7 +11,9 @@ OS_Haiku::OS_Haiku() { - AudioDriverManagerSW::add_driver(&driver_dummy); +#ifdef MEDIA_KIT_ENABLED + AudioDriverManagerSW::add_driver(&driver_media_kit); +#endif }; void OS_Haiku::run() { diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index a7a8bee522..f88b8182f8 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -11,7 +11,7 @@ #include "servers/audio/sample_manager_sw.h" #include "servers/spatial_sound/spatial_sound_server_sw.h" #include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" -#include "servers/audio/audio_driver_dummy.h" +#include "drivers/media_kit/audio_driver_media_kit.h" #include "context_gl_haiku.h" #include "haiku_application.h" @@ -34,7 +34,9 @@ private: SpatialSoundServerSW* spatial_sound_server; SpatialSound2DServerSW* spatial_sound_2d_server; - AudioDriverDummy driver_dummy; // TODO: use a real driver +#ifdef MEDIA_KIT_ENABLED + AudioDriverMediaKit driver_media_kit; +#endif #if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) ContextGL_Haiku* context_gl; -- cgit v1.2.3 From 5ffd818fb195a6e9bea48ec03ad52a77080a8d25 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sat, 25 Jul 2015 21:16:07 -0300 Subject: Duplicate GraphNode(s) [Control+D] --- scene/gui/graph_edit.cpp | 10 ++++- scene/gui/graph_node.cpp | 18 +++++---- scene/resources/shader_graph.cpp | 41 +++++++++++++++++++++ scene/resources/shader_graph.h | 4 ++ .../editor/plugins/shader_graph_editor_plugin.cpp | 43 ++++++++++++++++++++-- tools/editor/plugins/shader_graph_editor_plugin.h | 2 + 6 files changed, 106 insertions(+), 12 deletions(-) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index 003486dcf1..a81542ea17 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -534,7 +534,7 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { top_layer->update(); } - if (p_ev.type== InputEvent::MOUSE_BUTTON) { + if (p_ev.type==InputEvent::MOUSE_BUTTON) { const InputEventMouseButton &b=p_ev.mouse_button; @@ -667,6 +667,11 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { top_layer->update(); } } + + if (p_ev.type==InputEvent::KEY && p_ev.key.scancode==KEY_D && p_ev.key.pressed && p_ev.key.mod.command) { + emit_signal("duplicate_nodes_request"); + accept_event(); + } } void GraphEdit::clear_connections() { @@ -723,6 +728,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("connection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); + ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); ADD_SIGNAL(MethodInfo("_begin_node_move")); ADD_SIGNAL(MethodInfo("_end_node_move")); } @@ -730,6 +736,8 @@ void GraphEdit::_bind_methods() { GraphEdit::GraphEdit() { + set_focus_mode(FOCUS_ALL); + top_layer=NULL; top_layer=memnew(GraphEditFilter(this)); add_child(top_layer); diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index f0917aa4d1..5efc9757b7 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -525,15 +525,17 @@ Color GraphNode::get_connection_output_color(int p_idx) { void GraphNode::_input_event(const InputEvent& p_ev) { - if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { - - Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); - if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { - emit_signal("close_request"); - return; + if (p_ev.type==InputEvent::MOUSE_BUTTON) { + get_parent_control()->grab_focus(); + if(p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) { + + Vector2 mpos = Vector2(p_ev.mouse_button.x,p_ev.mouse_button.y); + if (close_rect.size!=Size2() && close_rect.has_point(mpos)) { + emit_signal("close_request"); + return; + } + emit_signal("raise_request"); } - emit_signal("raise_request"); - } } diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index a0766ff317..108aad3c56 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -824,6 +824,47 @@ float ShaderGraph::texture_node_get_filter_strength(ShaderType p_type,float p_id return arr[1]; } +void ShaderGraph::duplicate_nodes(ShaderType p_which, List &p_nodes) +{ + //Create new node IDs + Map duplicates = Map(); + int i=1; + for(List::Element *E=p_nodes.front();E; E=E->next()) { + while (shader[p_which].node_map.has(i)) + i++; + duplicates.insert(E->get(), i); + i++; + } + + for(List::Element *E = p_nodes.front();E; E=E->next()) { + + const Node &n=shader[p_which].node_map[E->get()]; + Node nn=n; + nn.id=duplicates.find(n.id)->get(); + nn.pos += Vector2(0,100); + for (Map::Element *C=nn.connections.front();C;C=C->next()) { + SourceSlot &c=C->get(); + if (p_nodes.find(c.id)) + c.id=duplicates.find(c.id)->get(); + } + shader[p_which].node_map[nn.id]=nn; + } + _request_update(); +} + +List ShaderGraph::generate_ids(ShaderType p_type, int count) +{ + List ids = List(); + int i=1; + while (ids.size() < count) { + while (shader[p_type].node_map.has(i)) + i++; + ids.push_back(i); + i++; + } + return ids; +} + void ShaderGraph::scalar_op_node_set_op(ShaderType p_type,float p_id,ScalarOp p_op){ diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index fd6540a747..d3a297cd6c 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -216,6 +216,10 @@ public: void texture_node_set_filter_strength(ShaderType p_which,float p_id,float p_strength); float texture_node_get_filter_strength(ShaderType p_which,float p_id) const; + void duplicate_nodes(ShaderType p_which, List &p_nodes); + + List generate_ids(ShaderType p_type, int count); + enum ScalarOp { SCALAR_OP_ADD, SCALAR_OP_SUB, diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 6e95432b99..3ab536ab6e 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -1184,6 +1184,43 @@ void ShaderGraphView::_move_node(int p_id,const Vector2& p_to) { graph->node_set_pos(type,p_id,p_to); } +void ShaderGraphView::_duplicate_nodes_request() +{ + Array s_id; + + for(Map::Element *E=node_map.front();E;E=E->next()) { + ShaderGraph::NodeType t=graph->node_get_type(type, E->key()); + if (t==ShaderGraph::NODE_OUTPUT || t==ShaderGraph::NODE_INPUT) + continue; + GraphNode *gn = E->get(); + if (gn && gn->is_selected()) + s_id.push_back(E->key()); + } + + if (s_id.size()==0) + return; + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Duplicate Graph Node(s)"); + ur->add_do_method(this,"_duplicate_nodes",s_id); + List n_ids = graph->generate_ids(type, s_id.size()); + for (List::Element *E=n_ids.front();E;E=E->next()) + ur->add_undo_method(graph.ptr(),"node_remove",type,E->get()); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + +} + +void ShaderGraphView::_duplicate_nodes(Array &p_nodes) +{ + List n = List(); + for (int i=0; iduplicate_nodes(type, n); + call_deferred("_update_graph"); +} + void ShaderGraphView::_create_node(int p_id) { @@ -2087,8 +2124,6 @@ void ShaderGraphView::_update_graph() { graph_edit->connect_node(node_map[E->get().src_id]->get_name(),E->get().src_slot,node_map[E->get().dst_id]->get_name(),E->get().dst_slot); } - - } void ShaderGraphView::_sg_updated() { @@ -2175,6 +2210,8 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_node_removed",&ShaderGraphView::_node_removed); ObjectTypeDB::bind_method("_connection_request",&ShaderGraphView::_connection_request); ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); + ObjectTypeDB::bind_method("_duplicate_nodes_request", &ShaderGraphView::_duplicate_nodes_request); + ObjectTypeDB::bind_method("_duplicate_nodes", &ShaderGraphView::_duplicate_nodes); ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); @@ -2250,7 +2287,6 @@ void ShaderGraphEditor::_popup_requested(const Vector2 &p_position) popup->set_invalidate_click_until_motion(); } - void ShaderGraphEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { @@ -2349,6 +2385,7 @@ ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { tabs->add_child(graph_edits[i]->get_graph_edit()); graph_edits[i]->get_graph_edit()->connect("connection_request",graph_edits[i],"_connection_request"); graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); + graph_edits[i]->get_graph_edit()->connect("duplicate_nodes_request", graph_edits[i], "_duplicate_nodes_request"); graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); graph_edits[i]->get_graph_edit()->set_right_disconnects(true); } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index 5f93b9df7d..faf6d7d64e 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -145,6 +145,8 @@ class ShaderGraphView : public Node { void _node_moved(const Vector2& p_from, const Vector2& p_to,int p_id); void _end_node_move(); void _move_node(int p_id,const Vector2& p_to); + void _duplicate_nodes_request(); + void _duplicate_nodes(Array &p_nodes); void _scalar_const_changed(double p_value,int p_id); void _vec_const_changed(double p_value, int p_id, Array p_arr); -- cgit v1.2.3 From add0105c4e89e586fb3d3a9646a9ffc747d2e881 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sat, 25 Jul 2015 22:05:45 -0300 Subject: Little fix: don't create an empty undo/redo command when trying to add a second Input GraphNode --- scene/resources/shader_graph.cpp | 9 +++++++++ scene/resources/shader_graph.h | 2 ++ tools/editor/plugins/shader_graph_editor_plugin.cpp | 3 +++ 3 files changed, 14 insertions(+) diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index 108aad3c56..9522667698 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -142,6 +142,15 @@ ShaderGraph::GraphError ShaderGraph::get_graph_error(ShaderType p_type) const { return shader[p_type].error; } +int ShaderGraph::node_count(ShaderType p_which, int p_type) +{ + int count=0; + for (Map::Element *E=shader[p_which].node_map.front();E;E=E->next()) + if (E->get().type==p_type) + count++; + return count; +} + void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("_update_shader"),&ShaderGraph::_update_shader); diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h index d3a297cd6c..b93567538d 100644 --- a/scene/resources/shader_graph.h +++ b/scene/resources/shader_graph.h @@ -365,6 +365,8 @@ public: GraphError get_graph_error(ShaderType p_type) const; + int node_count(ShaderType p_which, int p_type); + static int get_type_input_count(NodeType p_type); static int get_type_output_count(NodeType p_type); static SlotType get_type_input_type(NodeType p_type,int p_idx); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 3ab536ab6e..370688d6f5 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -2162,6 +2162,9 @@ void ShaderGraphView::_notification(int p_what) { void ShaderGraphView::add_node(int p_type, const Vector2 &location) { + if ((p_type==ShaderGraph::NODE_INPUT||p_type==ShaderGraph::NODE_INPUT) && graph->node_count(type, p_type)>0) + return; + List existing; graph->get_node_list(type,&existing); existing.sort(); -- cgit v1.2.3 From d7279ddaf2aa98ed962d84d466f21dc2f39522c9 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sun, 26 Jul 2015 21:57:27 -0300 Subject: Delete selected nodes with the Delete key --- scene/gui/graph_edit.cpp | 7 ++++ .../editor/plugins/shader_graph_editor_plugin.cpp | 41 ++++++++++++++++++++++ tools/editor/plugins/shader_graph_editor_plugin.h | 1 + 3 files changed, 49 insertions(+) diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp index a81542ea17..deb3151798 100644 --- a/scene/gui/graph_edit.cpp +++ b/scene/gui/graph_edit.cpp @@ -672,6 +672,12 @@ void GraphEdit::_input_event(const InputEvent& p_ev) { emit_signal("duplicate_nodes_request"); accept_event(); } + + if (p_ev.type==InputEvent::KEY && p_ev.key.scancode==KEY_DELETE && p_ev.key.pressed) { + emit_signal("delete_nodes_request"); + accept_event(); + } + } void GraphEdit::clear_connections() { @@ -729,6 +735,7 @@ void GraphEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("disconnection_request",PropertyInfo(Variant::STRING,"from"),PropertyInfo(Variant::INT,"from_slot"),PropertyInfo(Variant::STRING,"to"),PropertyInfo(Variant::INT,"to_slot"))); ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2,"p_position"))); ADD_SIGNAL(MethodInfo("duplicate_nodes_request")); + ADD_SIGNAL(MethodInfo("delete_nodes_request")); ADD_SIGNAL(MethodInfo("_begin_node_move")); ADD_SIGNAL(MethodInfo("_end_node_move")); } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 370688d6f5..b2de10ca20 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -1221,6 +1221,45 @@ void ShaderGraphView::_duplicate_nodes(Array &p_nodes) call_deferred("_update_graph"); } +void ShaderGraphView::_delete_nodes_request() +{ + List s_id=List(); + + for(Map::Element *E=node_map.front();E;E=E->next()) { + ShaderGraph::NodeType t=graph->node_get_type(type, E->key()); + if (t==ShaderGraph::NODE_OUTPUT) + continue; + GraphNode *gn = E->get(); + if (gn && gn->is_selected()) + s_id.push_back(E->key()); + } + + if (s_id.size()==0) + return; + + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Delete Shader Graph Node(s)"); + + for (List::Element *N=s_id.front();N;N=N->next()) { + ur->add_do_method(graph.ptr(),"node_remove",type,N->get()); + ur->add_undo_method(graph.ptr(),"node_add",type,graph->node_get_type(type,N->get()),N->get()); + ur->add_undo_method(graph.ptr(),"node_set_state",type,N->get(),graph->node_get_state(type,N->get())); + List conns; + + graph->get_node_connections(type,&conns); + for(List::Element *E=conns.front();E;E=E->next()) { + + if (E->get().dst_id==N->get() || E->get().src_id==N->get()) { + ur->add_undo_method(graph.ptr(),"connect_node",type,E->get().src_id,E->get().src_slot,E->get().dst_id,E->get().dst_slot); + } + } + } + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + +} + void ShaderGraphView::_create_node(int p_id) { @@ -2215,6 +2254,7 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_disconnection_request",&ShaderGraphView::_disconnection_request); ObjectTypeDB::bind_method("_duplicate_nodes_request", &ShaderGraphView::_duplicate_nodes_request); ObjectTypeDB::bind_method("_duplicate_nodes", &ShaderGraphView::_duplicate_nodes); + ObjectTypeDB::bind_method("_delete_nodes_request", &ShaderGraphView::_delete_nodes_request); ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); @@ -2390,6 +2430,7 @@ ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { graph_edits[i]->get_graph_edit()->connect("disconnection_request",graph_edits[i],"_disconnection_request"); graph_edits[i]->get_graph_edit()->connect("duplicate_nodes_request", graph_edits[i], "_duplicate_nodes_request"); graph_edits[i]->get_graph_edit()->connect("popup_request",this,"_popup_requested"); + graph_edits[i]->get_graph_edit()->connect("delete_nodes_request",graph_edits[i],"_delete_nodes_request"); graph_edits[i]->get_graph_edit()->set_right_disconnects(true); } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index faf6d7d64e..36443efeb0 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -147,6 +147,7 @@ class ShaderGraphView : public Node { void _move_node(int p_id,const Vector2& p_to); void _duplicate_nodes_request(); void _duplicate_nodes(Array &p_nodes); + void _delete_nodes_request(); void _scalar_const_changed(double p_value,int p_id); void _vec_const_changed(double p_value, int p_id, Array p_arr); -- cgit v1.2.3 From 7a516d13e259e0d26d09521188443bf1eab893df Mon Sep 17 00:00:00 2001 From: Federico Pacheco Date: Tue, 4 Aug 2015 01:44:38 -0300 Subject: ParallaxBackground: added option to ignore camera zoom --- scene/2d/parallax_background.cpp | 20 +++++++++++++++++++- scene/2d/parallax_background.h | 4 ++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp index 109546bde3..8bb4eb55ba 100644 --- a/scene/2d/parallax_background.cpp +++ b/scene/2d/parallax_background.cpp @@ -110,7 +110,10 @@ void ParallaxBackground::_update_scroll() { if (!l) continue; - l->set_base_offset_and_scale(ofs,scale); + if (ignore_camera_zoom) + l->set_base_offset_and_scale(ofs, 1.0); + else + l->set_base_offset_and_scale(ofs, scale); } } @@ -165,6 +168,18 @@ Point2 ParallaxBackground::get_limit_end() const { return limit_end; } +void ParallaxBackground::set_ignore_camera_zoom(bool ignore){ + + ignore_camera_zoom = ignore; + +} + +bool ParallaxBackground::is_ignore_camera_zoom(){ + + return ignore_camera_zoom; + +} + void ParallaxBackground::_bind_methods() { ObjectTypeDB::bind_method(_MD("_camera_moved"),&ParallaxBackground::_camera_moved); @@ -178,6 +193,8 @@ void ParallaxBackground::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_limit_begin"),&ParallaxBackground::get_limit_begin); ObjectTypeDB::bind_method(_MD("set_limit_end","ofs"),&ParallaxBackground::set_limit_end); ObjectTypeDB::bind_method(_MD("get_limit_end"),&ParallaxBackground::get_limit_end); + ObjectTypeDB::bind_method(_MD("set_ignore_camera_zoom"), &ParallaxBackground::set_ignore_camera_zoom); + ObjectTypeDB::bind_method(_MD("is_ignore_camera_zoom"), &ParallaxBackground::is_ignore_camera_zoom); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/offset"),_SCS("set_scroll_offset"),_SCS("get_scroll_offset")); @@ -185,6 +202,7 @@ void ParallaxBackground::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/base_scale"),_SCS("set_scroll_base_scale"),_SCS("get_scroll_base_scale")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/limit_begin"),_SCS("set_limit_begin"),_SCS("get_limit_begin")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"scroll/limit_end"),_SCS("set_limit_end"),_SCS("get_limit_end")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL, "scroll/ignore_camera_zoom"), _SCS("set_ignore_camera_zoom"), _SCS("is_ignore_camera_zoom")); } diff --git a/scene/2d/parallax_background.h b/scene/2d/parallax_background.h index 363236b2ad..8dede07a16 100644 --- a/scene/2d/parallax_background.h +++ b/scene/2d/parallax_background.h @@ -44,6 +44,7 @@ class ParallaxBackground : public CanvasLayer { String group_name; Point2 limit_begin; Point2 limit_end; + bool ignore_camera_zoom; void _update_scroll(); protected: @@ -72,6 +73,9 @@ public: void set_limit_end(const Point2& p_ofs); Point2 get_limit_end() const; + void set_ignore_camera_zoom(bool ignore); + bool is_ignore_camera_zoom(); + ParallaxBackground(); }; -- cgit v1.2.3 From 80943d77a4318822f888ea81e87d77c53d6047d7 Mon Sep 17 00:00:00 2001 From: volzhs Date: Tue, 11 Aug 2015 22:39:59 +0900 Subject: prevent to change tool mode when control or shift key is pressed --- tools/editor/plugins/canvas_item_editor_plugin.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index f2738f0a62..9469b79ea0 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -144,6 +144,9 @@ void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) { if (!is_visible()) return; + if (p_ev.key.mod.control || p_ev.key.mod.shift) + // prevent to change tool mode when control or shift key is pressed + return; if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_Q) _tool_select(TOOL_SELECT); if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_W) -- cgit v1.2.3 From edabbcd064372ff036e01735f6b236f472d80c93 Mon Sep 17 00:00:00 2001 From: volzhs Date: Tue, 11 Aug 2015 22:52:43 +0900 Subject: remove shift key check because shift + v in use with tool mode --- tools/editor/plugins/canvas_item_editor_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp index 9469b79ea0..e2f39b85ab 100644 --- a/tools/editor/plugins/canvas_item_editor_plugin.cpp +++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp @@ -144,8 +144,8 @@ void CanvasItemEditor::_unhandled_key_input(const InputEvent& p_ev) { if (!is_visible()) return; - if (p_ev.key.mod.control || p_ev.key.mod.shift) - // prevent to change tool mode when control or shift key is pressed + if (p_ev.key.mod.control) + // prevent to change tool mode when control key is pressed return; if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode==KEY_Q) _tool_select(TOOL_SELECT); -- cgit v1.2.3 From f48ce8901ab4fb74dd1a2de15b75895d0cb08fd8 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Wed, 12 Aug 2015 21:40:45 +0300 Subject: Haiku: remove unneeded code --- platform/haiku/haiku_direct_window.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index e7577602ca..2097ace497 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -94,13 +94,9 @@ void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { case B_WINDOW_RESIZED: HandleWindowResized(message); - //view->UnlockGL(); - //BDirectWindow::DispatchMessage(message, handler); - //view->LockGL(); break; case LOCKGL_MSG: - ERR_PRINT("LOCKGL"); view->LockGL(); break; -- cgit v1.2.3 From ced44b45d3590e6c2149fd83792dbf702321aff5 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Wed, 12 Aug 2015 22:14:40 +0300 Subject: Haiku: remove unneeded code --- platform/haiku/detect.py | 2 +- platform/haiku/haiku_application.cpp | 2 +- platform/haiku/haiku_application.h | 2 -- platform/haiku/haiku_direct_window.cpp | 7 ------- platform/haiku/haiku_gl_view.cpp | 15 +-------------- platform/haiku/haiku_gl_view.h | 2 -- 6 files changed, 3 insertions(+), 27 deletions(-) diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index f4198e50cd..19fe2f79fb 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -27,7 +27,7 @@ def get_flags(): ] def configure(env): - is64=sys.maxsize > 2**32 + is64 = sys.maxsize > 2**32 if (env["bits"]=="default"): if (is64): diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp index 56024f605d..ea20d73729 100644 --- a/platform/haiku/haiku_application.cpp +++ b/platform/haiku/haiku_application.cpp @@ -1,7 +1,7 @@ #include "haiku_application.h" HaikuApplication::HaikuApplication() - : BApplication("application/x-vnd.Haiku-GLDirectMode") + : BApplication("application/x-vnd.Godot") { } diff --git a/platform/haiku/haiku_application.h b/platform/haiku/haiku_application.h index 995a917d62..a64b01c94d 100644 --- a/platform/haiku/haiku_application.h +++ b/platform/haiku/haiku_application.h @@ -8,8 +8,6 @@ class HaikuApplication : public BApplication { public: HaikuApplication(); -//private: -// HaikuDirectWindow* window; }; #endif diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index 2097ace497..3914ee272a 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -55,8 +55,6 @@ void HaikuDirectWindow::DirectConnected(direct_buffer_info* info) { void HaikuDirectWindow::MessageReceived(BMessage* message) { switch (message->what) { case REDRAW_MSG: - Sync(); - if (Main::iteration() == true) { view->EnableDirectMode(false); Quit(); @@ -110,8 +108,6 @@ void HaikuDirectWindow::DispatchMessage(BMessage* message, BHandler* handler) { } void HaikuDirectWindow::HandleMouseButton(BMessage* message) { - message->PrintToStream(); - BPoint where; if (message->FindPoint("where", &where) != B_OK) { return; @@ -236,7 +232,6 @@ void HaikuDirectWindow::HandleMouseWheelChanged(BMessage* message) { } void HaikuDirectWindow::HandleKeyboardEvent(BMessage* message) { - message->PrintToStream(); int32 raw_char = 0; int32 key = 0; int32 modifiers = 0; @@ -278,8 +273,6 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage* message) { } void HaikuDirectWindow::HandleKeyboardModifierEvent(BMessage* message) { - message->PrintToStream(); - int32 old_modifiers = 0; int32 modifiers = 0; diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp index 8adab96a87..481d6098a7 100644 --- a/platform/haiku/haiku_gl_view.cpp +++ b/platform/haiku/haiku_gl_view.cpp @@ -2,7 +2,7 @@ #include "haiku_gl_view.h" HaikuGLView::HaikuGLView(BRect frame, uint32 type) - : BGLView(frame, "SampleGLView", B_FOLLOW_ALL_SIDES, 0, type) + : BGLView(frame, "GodotGLView", B_FOLLOW_ALL_SIDES, 0, type) { } @@ -16,16 +16,3 @@ void HaikuGLView::AttachedToWindow(void) { void HaikuGLView::Draw(BRect updateRect) { Main::force_redraw(); } - -void HaikuGLView::MessageReceived(BMessage* msg) -{ - // TODO: remove if not needed - switch (msg->what) { - default: - BGLView::MessageReceived(msg); - } -} - -void HaikuGLView::MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage) { - ERR_PRINT("MouseMoved()"); -} diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h index 78ebb513a8..f44b6d4325 100644 --- a/platform/haiku/haiku_gl_view.h +++ b/platform/haiku/haiku_gl_view.h @@ -9,8 +9,6 @@ class HaikuGLView : public BGLView public: HaikuGLView(BRect frame, uint32 type); virtual void AttachedToWindow(void); - virtual void MessageReceived(BMessage* msg); - virtual void MouseMoved (BPoint where, uint32 code, const BMessage *dragMessage); virtual void Draw(BRect updateRect); }; -- cgit v1.2.3 From cff2509ecd06967c0d214dc0cf3d31c392091c99 Mon Sep 17 00:00:00 2001 From: Alexander Holland Date: Wed, 12 Aug 2015 22:24:21 +0200 Subject: close all parent PopupMenus fix --- scene/gui/popup_menu.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index e706053592..275965b372 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -738,10 +738,18 @@ int PopupMenu::find_item_by_accelerator(uint32_t p_accel) const { void PopupMenu::activate_item(int p_item) { - ERR_FAIL_INDEX(p_item,items.size()); ERR_FAIL_COND(items[p_item].separator); emit_signal("item_pressed",items[p_item].ID); + + //hide all parent PopupMenue's + Node *next = get_parent(); + PopupMenu *pop = next->cast_to(); + while (pop) { + pop->hide(); + next = next->get_parent(); + pop = next->cast_to(); + } hide(); } -- cgit v1.2.3 From f6eff87793a3200e728bcc4dc33dc9c612d73036 Mon Sep 17 00:00:00 2001 From: Alexander Holland Date: Wed, 12 Aug 2015 22:35:37 +0200 Subject: update scene tabs on save - fix --- tools/editor/editor_node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index b0a2c568de..f51c4e8214 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -918,6 +918,7 @@ void EditorNode::_save_scene(String p_file) { //EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type()); set_current_version(editor_data.get_undo_redo().get_version()); _update_title(); + _update_scene_tabs(); } else { _dialog_display_file_error(p_file,err); @@ -1323,7 +1324,6 @@ void EditorNode::_dialog_action(String p_file) { default: { //save scene? - if (file->get_mode()==FileDialog::MODE_SAVE_FILE) { //_save_scene(p_file); -- cgit v1.2.3 From 69710055f0af99838d669b2e3fa3f1ae8bf6683d Mon Sep 17 00:00:00 2001 From: Mavhod Date: Thu, 13 Aug 2015 14:09:21 +0700 Subject: get_date on Linux tm_mon is 0-11 --- drivers/unix/os_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 314e13cee4..ba151b0f44 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -242,7 +242,7 @@ OS::Date OS_Unix::get_date(bool utc) const { lt=localtime(&t); Date ret; ret.year=1900+lt->tm_year; - ret.month=(Month)lt->tm_mon; + ret.month=(Month)lt->tm_mon + 1; ret.day=lt->tm_mday; ret.weekday=(Weekday)lt->tm_wday; ret.dst=lt->tm_isdst; -- cgit v1.2.3 From 3942117bbf1b669fb81628bb401d16ad83f1f2bb Mon Sep 17 00:00:00 2001 From: Mavhod Date: Thu, 13 Aug 2015 18:56:13 +0700 Subject: add () Sorry, firt time I put it but had no compiled for check. --- drivers/unix/os_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index ba151b0f44..975affbb82 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -242,7 +242,7 @@ OS::Date OS_Unix::get_date(bool utc) const { lt=localtime(&t); Date ret; ret.year=1900+lt->tm_year; - ret.month=(Month)lt->tm_mon + 1; + ret.month=(Month)(lt->tm_mon + 1); ret.day=lt->tm_mday; ret.weekday=(Weekday)lt->tm_wday; ret.dst=lt->tm_isdst; -- cgit v1.2.3 From b038a2c3c21b7be4cc1db0aca6c84ddaf57132cf Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Thu, 13 Aug 2015 22:36:43 +0300 Subject: Haiku: update logo.png --- platform/haiku/logo.png | Bin 2055 -> 1361 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/platform/haiku/logo.png b/platform/haiku/logo.png index c40214d6de..42d7728da8 100644 Binary files a/platform/haiku/logo.png and b/platform/haiku/logo.png differ -- cgit v1.2.3 From 2a757a6ad4ef4e7767b7d3ef7e177ec6613ef6d1 Mon Sep 17 00:00:00 2001 From: Kostadin Damyanov Date: Fri, 14 Aug 2015 22:52:28 +0300 Subject: Haiku: move the audio driver to platform/haiku --- drivers/SCsub | 1 - drivers/media_kit/SCsub | 5 - drivers/media_kit/audio_driver_media_kit.cpp | 143 --------------------------- drivers/media_kit/audio_driver_media_kit.h | 72 -------------- platform/haiku/SCsub | 3 +- platform/haiku/audio_driver_media_kit.cpp | 143 +++++++++++++++++++++++++++ platform/haiku/audio_driver_media_kit.h | 72 ++++++++++++++ platform/haiku/os_haiku.h | 2 +- 8 files changed, 218 insertions(+), 223 deletions(-) delete mode 100644 drivers/media_kit/SCsub delete mode 100644 drivers/media_kit/audio_driver_media_kit.cpp delete mode 100644 drivers/media_kit/audio_driver_media_kit.h create mode 100644 platform/haiku/audio_driver_media_kit.cpp create mode 100644 platform/haiku/audio_driver_media_kit.h diff --git a/drivers/SCsub b/drivers/SCsub index bed1f22a64..3028139f50 100644 --- a/drivers/SCsub +++ b/drivers/SCsub @@ -12,7 +12,6 @@ SConscript('windows/SCsub'); SConscript('gles2/SCsub'); SConscript('gl_context/SCsub'); SConscript('openssl/SCsub'); -SConscript('media_kit/SCsub'); if (env["png"]=="yes"): SConscript("png/SCsub"); diff --git a/drivers/media_kit/SCsub b/drivers/media_kit/SCsub deleted file mode 100644 index 9fbb467baa..0000000000 --- a/drivers/media_kit/SCsub +++ /dev/null @@ -1,5 +0,0 @@ -Import('env') - -env.add_source_files(env.drivers_sources,"*.cpp") - -Export('env') diff --git a/drivers/media_kit/audio_driver_media_kit.cpp b/drivers/media_kit/audio_driver_media_kit.cpp deleted file mode 100644 index 3fabe4f96f..0000000000 --- a/drivers/media_kit/audio_driver_media_kit.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/*************************************************************************/ -/* audio_driver_media_kit.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "audio_driver_media_kit.h" - -#ifdef MEDIA_KIT_ENABLED - -#include "globals.h" - -int32_t* AudioDriverMediaKit::samples_in = NULL; - -Error AudioDriverMediaKit::init() { - active = false; - - mix_rate = 44100; - output_format = OUTPUT_STEREO; - channels = 2; - - int latency = GLOBAL_DEF("audio/output_latency", 25); - buffer_size = nearest_power_of_2(latency * mix_rate / 1000); - samples_in = memnew_arr(int32_t, buffer_size * channels); - - media_raw_audio_format format; - format = media_raw_audio_format::wildcard; - format.frame_rate = mix_rate; - format.channel_count = channels; - format.format = media_raw_audio_format::B_AUDIO_INT; - format.byte_order = B_MEDIA_LITTLE_ENDIAN; - format.buffer_size = buffer_size * sizeof(int32_t) * channels; - - player = new BSoundPlayer( - &format, - "godot_sound_server", - AudioDriverMediaKit::PlayBuffer, - NULL, - this - ); - - if (player->InitCheck() != B_OK) { - fprintf(stderr, "MediaKit ERR: can not create a BSoundPlayer instance\n"); - ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN); - } - - mutex = Mutex::create(); - player->Start(); - - return OK; -} - -void AudioDriverMediaKit::PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format) { - AudioDriverMediaKit* ad = (AudioDriverMediaKit*) cookie; - int32_t* buf = (int32_t*) buffer; - - if (!ad->active) { - for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { - AudioDriverMediaKit::samples_in[i] = 0; - } - } else { - ad->lock(); - ad->audio_server_process(ad->buffer_size, AudioDriverMediaKit::samples_in); - ad->unlock(); - } - - for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { - buf[i] = AudioDriverMediaKit::samples_in[i]; - } -} - -void AudioDriverMediaKit::start() { - active = true; -} - -int AudioDriverMediaKit::get_mix_rate() const { - return mix_rate; -} - -AudioDriverSW::OutputFormat AudioDriverMediaKit::get_output_format() const { - return output_format; -} - -void AudioDriverMediaKit::lock() { - if (!mutex) - return; - - mutex->lock(); -} - -void AudioDriverMediaKit::unlock() { - if (!mutex) - return; - - mutex->unlock(); -} - -void AudioDriverMediaKit::finish() { - if (player) - delete player; - - if (samples_in) { - memdelete_arr(samples_in); - }; - - if (mutex) { - memdelete(mutex); - mutex = NULL; - } -} - -AudioDriverMediaKit::AudioDriverMediaKit() { - mutex = NULL; - player = NULL; -} - -AudioDriverMediaKit::~AudioDriverMediaKit() { - -} - -#endif diff --git a/drivers/media_kit/audio_driver_media_kit.h b/drivers/media_kit/audio_driver_media_kit.h deleted file mode 100644 index a23ec447f1..0000000000 --- a/drivers/media_kit/audio_driver_media_kit.h +++ /dev/null @@ -1,72 +0,0 @@ -/*************************************************************************/ -/* audio_driver_media_kit.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "servers/audio/audio_server_sw.h" - -#ifdef MEDIA_KIT_ENABLED - -#include "core/os/thread.h" -#include "core/os/mutex.h" - -#include // needed for image_id -#include - -class AudioDriverMediaKit : public AudioDriverSW { - Mutex* mutex; - - BSoundPlayer* player; - static int32_t* samples_in; - - static void PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format); - - unsigned int mix_rate; - OutputFormat output_format; - unsigned int buffer_size; - int channels; - - bool active; - -public: - - const char* get_name() const { - return "MediaKit"; - }; - - virtual Error init(); - virtual void start(); - virtual int get_mix_rate() const; - virtual OutputFormat get_output_format() const; - virtual void lock(); - virtual void unlock(); - virtual void finish(); - - AudioDriverMediaKit(); - ~AudioDriverMediaKit(); -}; - -#endif diff --git a/platform/haiku/SCsub b/platform/haiku/SCsub index 88c9b8b464..859095fa5a 100644 --- a/platform/haiku/SCsub +++ b/platform/haiku/SCsub @@ -6,7 +6,8 @@ common_haiku = [ 'haiku_application.cpp', 'haiku_direct_window.cpp', 'haiku_gl_view.cpp', - 'key_mapping_haiku.cpp' + 'key_mapping_haiku.cpp', + 'audio_driver_media_kit.cpp' ] env.Program( diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp new file mode 100644 index 0000000000..3fabe4f96f --- /dev/null +++ b/platform/haiku/audio_driver_media_kit.cpp @@ -0,0 +1,143 @@ +/*************************************************************************/ +/* audio_driver_media_kit.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "audio_driver_media_kit.h" + +#ifdef MEDIA_KIT_ENABLED + +#include "globals.h" + +int32_t* AudioDriverMediaKit::samples_in = NULL; + +Error AudioDriverMediaKit::init() { + active = false; + + mix_rate = 44100; + output_format = OUTPUT_STEREO; + channels = 2; + + int latency = GLOBAL_DEF("audio/output_latency", 25); + buffer_size = nearest_power_of_2(latency * mix_rate / 1000); + samples_in = memnew_arr(int32_t, buffer_size * channels); + + media_raw_audio_format format; + format = media_raw_audio_format::wildcard; + format.frame_rate = mix_rate; + format.channel_count = channels; + format.format = media_raw_audio_format::B_AUDIO_INT; + format.byte_order = B_MEDIA_LITTLE_ENDIAN; + format.buffer_size = buffer_size * sizeof(int32_t) * channels; + + player = new BSoundPlayer( + &format, + "godot_sound_server", + AudioDriverMediaKit::PlayBuffer, + NULL, + this + ); + + if (player->InitCheck() != B_OK) { + fprintf(stderr, "MediaKit ERR: can not create a BSoundPlayer instance\n"); + ERR_FAIL_COND_V(player == NULL, ERR_CANT_OPEN); + } + + mutex = Mutex::create(); + player->Start(); + + return OK; +} + +void AudioDriverMediaKit::PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format) { + AudioDriverMediaKit* ad = (AudioDriverMediaKit*) cookie; + int32_t* buf = (int32_t*) buffer; + + if (!ad->active) { + for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { + AudioDriverMediaKit::samples_in[i] = 0; + } + } else { + ad->lock(); + ad->audio_server_process(ad->buffer_size, AudioDriverMediaKit::samples_in); + ad->unlock(); + } + + for (unsigned int i = 0; i < ad->buffer_size * ad->channels; i++) { + buf[i] = AudioDriverMediaKit::samples_in[i]; + } +} + +void AudioDriverMediaKit::start() { + active = true; +} + +int AudioDriverMediaKit::get_mix_rate() const { + return mix_rate; +} + +AudioDriverSW::OutputFormat AudioDriverMediaKit::get_output_format() const { + return output_format; +} + +void AudioDriverMediaKit::lock() { + if (!mutex) + return; + + mutex->lock(); +} + +void AudioDriverMediaKit::unlock() { + if (!mutex) + return; + + mutex->unlock(); +} + +void AudioDriverMediaKit::finish() { + if (player) + delete player; + + if (samples_in) { + memdelete_arr(samples_in); + }; + + if (mutex) { + memdelete(mutex); + mutex = NULL; + } +} + +AudioDriverMediaKit::AudioDriverMediaKit() { + mutex = NULL; + player = NULL; +} + +AudioDriverMediaKit::~AudioDriverMediaKit() { + +} + +#endif diff --git a/platform/haiku/audio_driver_media_kit.h b/platform/haiku/audio_driver_media_kit.h new file mode 100644 index 0000000000..a23ec447f1 --- /dev/null +++ b/platform/haiku/audio_driver_media_kit.h @@ -0,0 +1,72 @@ +/*************************************************************************/ +/* audio_driver_media_kit.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "servers/audio/audio_server_sw.h" + +#ifdef MEDIA_KIT_ENABLED + +#include "core/os/thread.h" +#include "core/os/mutex.h" + +#include // needed for image_id +#include + +class AudioDriverMediaKit : public AudioDriverSW { + Mutex* mutex; + + BSoundPlayer* player; + static int32_t* samples_in; + + static void PlayBuffer(void* cookie, void* buffer, size_t size, const media_raw_audio_format& format); + + unsigned int mix_rate; + OutputFormat output_format; + unsigned int buffer_size; + int channels; + + bool active; + +public: + + const char* get_name() const { + return "MediaKit"; + }; + + virtual Error init(); + virtual void start(); + virtual int get_mix_rate() const; + virtual OutputFormat get_output_format() const; + virtual void lock(); + virtual void unlock(); + virtual void finish(); + + AudioDriverMediaKit(); + ~AudioDriverMediaKit(); +}; + +#endif diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index f88b8182f8..57b72df3cf 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -11,8 +11,8 @@ #include "servers/audio/sample_manager_sw.h" #include "servers/spatial_sound/spatial_sound_server_sw.h" #include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" -#include "drivers/media_kit/audio_driver_media_kit.h" +#include "audio_driver_media_kit.h" #include "context_gl_haiku.h" #include "haiku_application.h" #include "haiku_direct_window.h" -- cgit v1.2.3 From 17fbd2067385aa3bcbfd676192cb57a9735596cf Mon Sep 17 00:00:00 2001 From: Julian Murgia - StraToN Date: Tue, 18 Aug 2015 20:27:01 +0200 Subject: Added close button to tab. Added 4 display policies for this close button (show always, show never, show active tab only, show hover). Set the scene tabs in editor to follow the hover policy. --- scene/gui/tabs.cpp | 250 +++++++++++++++++++++++++++++++++++++++++-- scene/gui/tabs.h | 20 ++++ tools/editor/editor_node.cpp | 15 +++ tools/editor/editor_node.h | 1 + 4 files changed, 280 insertions(+), 6 deletions(-) diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index a849d3ae72..6d84f028b3 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -64,6 +64,15 @@ Size2 Tabs::get_minimum_size() const { ms.width+=bms.width; ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height); } + + if (tabs[i].close_button.is_valid()) { + Ref cb=tabs[i].close_button; + Size2 bms = cb->get_size()+get_stylebox("button")->get_minimum_size(); + bms.width+=get_constant("hseparation"); + + ms.width+=bms.width; + ms.height=MAX(bms.height+tab_bg->get_minimum_size().height,ms.height); + } } return ms; @@ -77,22 +86,48 @@ void Tabs::_input_event(const InputEvent& p_event) { Point2 pos( p_event.mouse_motion.x, p_event.mouse_motion.y ); - int hover=-1; + int hover_buttons=-1; + hover=-1; for(int i=0;i=tabs[i].ofs_cache && pos.x=tabs[i].ofs_cache && pos.xget_string_size(s).width;; + int slen=font->get_string_size(s).width; lsize+=slen; Ref icon; @@ -211,6 +268,56 @@ void Tabs::_notification(int p_what) { } + // Close button + switch (cb_displaypolicy) { + case SHOW_ALWAYS: { + if (tabs[i].close_button.is_valid()) { + Ref style = get_stylebox("button"); + Ref rb=tabs[i].close_button; + + lsize+=get_constant("hseparation"); + lsize+=style->get_margin(MARGIN_LEFT); + lsize+=rb->get_width(); + lsize+=style->get_margin(MARGIN_RIGHT); + + } + } break; + case SHOW_ACTIVE_ONLY: { + if (i==current) { + if (tabs[i].close_button.is_valid()) { + Ref style = get_stylebox("button"); + Ref rb=tabs[i].close_button; + + lsize+=get_constant("hseparation"); + lsize+=style->get_margin(MARGIN_LEFT); + lsize+=rb->get_width(); + lsize+=style->get_margin(MARGIN_RIGHT); + + } + } + } break; + case SHOW_HOVER: { + if (i==current || i==hover) { + if (tabs[i].close_button.is_valid()) { + Ref style = get_stylebox("button"); + Ref rb=tabs[i].close_button; + + lsize+=get_constant("hseparation"); + lsize+=style->get_margin(MARGIN_LEFT); + lsize+=rb->get_width(); + lsize+=style->get_margin(MARGIN_RIGHT); + + } + } + } break; + case SHOW_NEVER: // by default, never show close button + default: { + // do nothing + } break; + + } + + Ref sb; int va; Color col; @@ -273,6 +380,103 @@ void Tabs::_notification(int p_what) { } + + + + // Close button + switch (cb_displaypolicy) { + case SHOW_ALWAYS: { + if (tabs[i].close_button.is_valid()) { + Ref style = get_stylebox("button"); + Ref cb=tabs[i].close_button; + + w+=get_constant("hseparation"); + + Rect2 cb_rect; + cb_rect.size=style->get_minimum_size()+cb->get_size(); + cb_rect.pos.x=w; + cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2; + + if (cb_hover==i) { + if (cb_pressing) + get_stylebox("button_pressed")->draw(ci,cb_rect); + else + style->draw(ci,cb_rect); + } + + w+=style->get_margin(MARGIN_LEFT); + + cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) )); + w+=cb->get_width(); + w+=style->get_margin(MARGIN_RIGHT); + tabs[i].cb_rect=cb_rect; + } + } break; + case SHOW_ACTIVE_ONLY: { + if (current==i) { + if (tabs[i].close_button.is_valid()) { + Ref style = get_stylebox("button"); + Ref cb=tabs[i].close_button; + + w+=get_constant("hseparation"); + + Rect2 cb_rect; + cb_rect.size=style->get_minimum_size()+cb->get_size(); + cb_rect.pos.x=w; + cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2; + + if (cb_hover==i) { + if (cb_pressing) + get_stylebox("button_pressed")->draw(ci,cb_rect); + else + style->draw(ci,cb_rect); + } + + w+=style->get_margin(MARGIN_LEFT); + + cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) )); + w+=cb->get_width(); + w+=style->get_margin(MARGIN_RIGHT); + tabs[i].cb_rect=cb_rect; + } + } + } break; + case SHOW_HOVER: { + if (current==i || hover==i) { + if (tabs[i].close_button.is_valid()) { + Ref style = get_stylebox("button"); + Ref cb=tabs[i].close_button; + + w+=get_constant("hseparation"); + + Rect2 cb_rect; + cb_rect.size=style->get_minimum_size()+cb->get_size(); + cb_rect.pos.x=w; + cb_rect.pos.y=sb->get_margin(MARGIN_TOP)+((sb_rect.size.y-sb_ms.y)-(cb_rect.size.y))/2; + + if (cb_hover==i) { + if (cb_pressing) + get_stylebox("button_pressed")->draw(ci,cb_rect); + else + style->draw(ci,cb_rect); + } + + w+=style->get_margin(MARGIN_LEFT); + + cb->draw(ci,Point2i( w,cb_rect.pos.y+style->get_margin(MARGIN_TOP) )); + w+=cb->get_width(); + w+=style->get_margin(MARGIN_RIGHT); + tabs[i].cb_rect=cb_rect; + } + } + } break; + case SHOW_NEVER: + default: { + // show nothing + } break; + + } + w+=sb->get_margin(MARGIN_RIGHT); tabs[i].size_cache=w-tabs[i].ofs_cache; @@ -358,11 +562,29 @@ Ref Tabs::get_tab_right_button(int p_tab) const{ } +void Tabs::set_tab_close_button(int p_tab, const Ref& p_close_button) { + ERR_FAIL_INDEX(p_tab, tabs.size()); + tabs[p_tab].close_button=p_close_button; + update(); + minimum_size_changed(); +} + + +Ref Tabs::get_tab_close_button(int p_tab) const{ + + ERR_FAIL_INDEX_V(p_tab,tabs.size(),Ref()); + return tabs[p_tab].close_button; + +} + void Tabs::add_tab(const String& p_str,const Ref& p_icon) { Tab t; t.text=p_str; t.icon=p_icon; + + t.close_button = get_icon("Close","EditorIcons"); + tabs.push_back(t); update(); @@ -394,6 +616,11 @@ void Tabs::remove_tab(int p_idx) { } +void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_cb_displaypolicy) { + cb_displaypolicy = p_cb_displaypolicy; +} + + void Tabs::set_tab_align(TabAlign p_align) { tab_align=p_align; @@ -423,14 +650,22 @@ void Tabs::_bind_methods() { ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab"))); ADD_SIGNAL(MethodInfo("right_button_pressed",PropertyInfo(Variant::INT,"tab"))); + ADD_SIGNAL(MethodInfo("tab_close",PropertyInfo(Variant::INT,"tab"))); + ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") ); BIND_CONSTANT( ALIGN_LEFT ); BIND_CONSTANT( ALIGN_CENTER ); BIND_CONSTANT( ALIGN_RIGHT ); + + BIND_CONSTANT( SHOW_ACTIVE_ONLY ); + BIND_CONSTANT( SHOW_ALWAYS ); + BIND_CONSTANT( SHOW_HOVER ); + BIND_CONSTANT( SHOW_NEVER ); } + Tabs::Tabs() { current=0; @@ -438,4 +673,7 @@ Tabs::Tabs() { rb_hover=-1; rb_pressing=false; + cb_hover=-1; + cb_pressing=false; + cb_displaypolicy = SHOW_NEVER; // Default : no close button } diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h index 5cb0d9e916..1a8352bc93 100644 --- a/scene/gui/tabs.h +++ b/scene/gui/tabs.h @@ -42,6 +42,14 @@ public: ALIGN_CENTER, ALIGN_RIGHT }; + + enum CloseButtonDisplayPolicy { + + SHOW_ALWAYS, + SHOW_ACTIVE_ONLY, + SHOW_HOVER, + SHOW_NEVER + }; private: @@ -53,6 +61,8 @@ private: int size_cache; Ref right_button; Rect2 rb_rect; + Ref close_button; + Rect2 cb_rect; }; Vector tabs; @@ -63,6 +73,12 @@ private: int rb_hover; bool rb_pressing; + int cb_hover; + bool cb_pressing; + CloseButtonDisplayPolicy cb_displaypolicy; + + int hover; // hovered tab + protected: void _input_event(const InputEvent& p_event); @@ -82,6 +98,10 @@ public: void set_tab_right_button(int p_tab,const Ref& p_right_button); Ref get_tab_right_button(int p_tab) const; + void set_tab_close_button(int p_tab, const Ref& p_close_button); + Ref get_tab_close_button(int p_tab) const; + void set_tab_close_display_policy(CloseButtonDisplayPolicy p_cb_displaypolicy); + void set_tab_align(TabAlign p_align); TabAlign get_tab_align() const; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index b0a2c568de..6321745caa 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -3620,6 +3620,7 @@ void EditorNode::_bind_methods() { ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene); ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version); ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed); + ObjectTypeDB::bind_method("_scene_tab_closed",&EditorNode::_scene_tab_closed); ObjectTypeDB::bind_method("_scene_tab_script_edited",&EditorNode::_scene_tab_script_edited); ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state); ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs); @@ -4072,6 +4073,17 @@ void EditorNode::_scene_tab_script_edited(int p_tab) { edit_resource(script); } +void EditorNode::_scene_tab_closed(int p_tab) { + set_current_scene(p_tab); + bool p_confirmed = true; + if (unsaved_cache) + p_confirmed = false; + + _menu_option_confirm(FILE_CLOSE, p_confirmed); + _update_scene_tabs(); +} + + void EditorNode::_scene_tab_changed(int p_tab) { @@ -4225,8 +4237,10 @@ EditorNode::EditorNode() { scene_tabs=memnew( Tabs ); scene_tabs->add_tab("unsaved"); scene_tabs->set_tab_align(Tabs::ALIGN_CENTER); + scene_tabs->set_tab_close_display_policy(Tabs::SHOW_HOVER); scene_tabs->connect("tab_changed",this,"_scene_tab_changed"); scene_tabs->connect("right_button_pressed",this,"_scene_tab_script_edited"); + scene_tabs->connect("tab_close", this, "_scene_tab_closed"); top_dark_vb->add_child(scene_tabs); //left left_l_hsplit = memnew( HSplitContainer ); @@ -4363,6 +4377,7 @@ EditorNode::EditorNode() { main_editor_tabs = memnew( Tabs ); main_editor_tabs->connect("tab_changed",this,"_editor_select"); + main_editor_tabs->set_tab_close_display_policy(Tabs::SHOW_NEVER); HBoxContainer *srth = memnew( HBoxContainer ); srt->add_child( srth ); Control *tec = memnew( Control ); diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index d40658a056..f08f413507 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -473,6 +473,7 @@ class EditorNode : public Node { void _dock_split_dragged(int ofs); void _dock_popup_exit(); void _scene_tab_changed(int p_tab); + void _scene_tab_closed(int p_tab); void _scene_tab_script_edited(int p_tab); Dictionary _get_main_scene_state(); -- cgit v1.2.3 From 32b52e80411d5bf23fc6add0a5ec67a24690c847 Mon Sep 17 00:00:00 2001 From: Joshua Olson <0joshua.olson1@gmail.com> Date: Wed, 26 Aug 2015 14:21:04 -0600 Subject: Fixed misspelled local variable for code clarity Specifically, tar(g)et_fps --- main/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 19ee1c115f..acc122233a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1454,9 +1454,9 @@ bool Main::iteration() { OS::get_singleton()->delay_usec( OS::get_singleton()->get_frame_delay()*1000 ); } - int taret_fps = OS::get_singleton()->get_target_fps(); - if (taret_fps>0) { - uint64_t time_step = 1000000L/taret_fps; + int target_fps = OS::get_singleton()->get_target_fps(); + if (target_fps>0) { + uint64_t time_step = 1000000L/target_fps; target_ticks += time_step; uint64_t current_ticks = OS::get_singleton()->get_ticks_usec(); if (current_ticksdelay_usec(target_ticks-current_ticks); -- cgit v1.2.3 From f0119c2e3c0ddb19cef1fdf6cfebb6697dabd14d Mon Sep 17 00:00:00 2001 From: "Eric R. Monson" Date: Fri, 28 Aug 2015 11:15:31 -0700 Subject: Properly free enemies after death in 3d platformer demo. Previously, they stuck around as invisible physics objects. This fix is much cleaner than my previous attempts, as it uses the ability to call a function from an animation as is done in the 2d platformer demo. --- demos/3d/platformer/enemy.gd | 3 ++- demos/3d/platformer/enemy.scn | Bin 37784 -> 38594 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/demos/3d/platformer/enemy.gd b/demos/3d/platformer/enemy.gd index cbbb2fe725..9b2e95a96d 100644 --- a/demos/3d/platformer/enemy.gd +++ b/demos/3d/platformer/enemy.gd @@ -91,4 +91,5 @@ func _ready(): # Initalization here pass - +func _die(): + queue_free() diff --git a/demos/3d/platformer/enemy.scn b/demos/3d/platformer/enemy.scn index 06d725061d..083582a85a 100644 Binary files a/demos/3d/platformer/enemy.scn and b/demos/3d/platformer/enemy.scn differ -- cgit v1.2.3 From ea448cb779c9268f6213a8e741cfc793704ca2fe Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sat, 29 Aug 2015 21:09:11 -0300 Subject: Edit default values. WARNING!!! Do not merge these changes, default values are not compiled into shaders yet! --- core/object.h | 64 +-- scene/resources/default_theme/default_theme.cpp | 8 +- .../resources/default_theme/graph_node_default.png | Bin 0 -> 289 bytes .../default_theme/graph_node_default_focus.png | Bin 0 -> 408 bytes scene/resources/default_theme/theme_data.h | 10 + scene/resources/shader_graph.cpp | 150 ++++-- scene/resources/shader_graph.h | 9 +- .../editor/plugins/shader_graph_editor_plugin.cpp | 437 ++++++++++++++-- tools/editor/plugins/shader_graph_editor_plugin.h | 6 + tools/editor/property_editor.cpp | 561 ++++++++++++--------- tools/editor/property_editor.h | 46 +- 11 files changed, 890 insertions(+), 401 deletions(-) create mode 100644 scene/resources/default_theme/graph_node_default.png create mode 100644 scene/resources/default_theme/graph_node_default_focus.png diff --git a/core/object.h b/core/object.h index eb0e78a8c3..981a83958c 100644 --- a/core/object.h +++ b/core/object.h @@ -49,7 +49,7 @@ enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. - PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step" + PROPERTY_HINT_RANGE, ///< hint_text = "min,max,step,slider; //slider is optional" PROPERTY_HINT_EXP_RANGE, ///< hint_text = "min,max,step", exponential edit PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing funciton (Math::ease) @@ -58,12 +58,12 @@ enum PropertyHint { PROPERTY_HINT_KEY_ACCEL, ///< hint_text= "length" (as integer) PROPERTY_HINT_FLAGS, ///< hint_text= "flag1,flag2,etc" (as bit flags) PROPERTY_HINT_ALL_FLAGS, - PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," + PROPERTY_HINT_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," PROPERTY_HINT_DIR, ///< a directort path must be passed PROPERTY_HINT_GLOBAL_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc," PROPERTY_HINT_GLOBAL_DIR, ///< a directort path must be passed PROPERTY_HINT_RESOURCE_TYPE, ///< a resource object type - PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines + PROPERTY_HINT_MULTILINE_TEXT, ///< used for string properties that can contain multiple lines PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color PROPERTY_HINT_IMAGE_COMPRESS_LOSSY, PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS, @@ -71,7 +71,7 @@ enum PropertyHint { }; enum PropertyUsageFlags { - + PROPERTY_USAGE_STORAGE=1, PROPERTY_USAGE_EDITOR=2, PROPERTY_USAGE_NETWORK=4, @@ -102,15 +102,15 @@ enum PropertyUsageFlags { #define ADD_PROPERTYINO( m_property, m_setter, m_getter, m_index ) ObjectTypeDB::add_property( get_type_static(), (m_property).added_usage(PROPERTY_USAGE_STORE_IF_NONONE), m_setter, m_getter, m_index ) struct PropertyInfo { - - Variant::Type type; + + Variant::Type type; String name; PropertyHint hint; - String hint_string; + String hint_string; uint32_t usage; _FORCE_INLINE_ PropertyInfo added_usage(int p_fl) const { PropertyInfo pi=*this; pi.usage|=p_fl; return pi; } - + PropertyInfo() { type=Variant::NIL; hint=PROPERTY_HINT_NONE; usage = PROPERTY_USAGE_DEFAULT; } PropertyInfo( Variant::Type p_type, const String p_name, PropertyHint p_hint=PROPERTY_HINT_NONE, const String& p_hint_string="",uint32_t p_usage=PROPERTY_USAGE_DEFAULT) { type=p_type; name=p_name; hint=p_hint; hint_string=p_hint_string; usage=p_usage; @@ -125,23 +125,23 @@ struct PropertyInfo { Array convert_property_list(const List * p_list); struct MethodInfo { - + String name; List arguments; Vector default_arguments; PropertyInfo return_val; uint32_t flags; int id; - + inline bool operator<(const MethodInfo& p_method) const { return id==p_method.id?(name < p_method.name):(id *p_list,bool p_reversed) const {}; virtual void _notificationv(int p_notification,bool p_reversed) {}; - + static String _get_category() { return ""; } static void _bind_methods(); bool _set(const StringName& p_name,const Variant &p_property) { return false; }; bool _get(const StringName& p_name,Variant &r_property) const { return false; }; void _get_property_list(List *p_list) const {}; void _notification(int p_notification) {}; - + _FORCE_INLINE_ static void (*_get_bind_methods())() { return &Object::_bind_methods; } @@ -431,13 +431,13 @@ protected: } _FORCE_INLINE_ void (Object::* (_get_get_property_list() const))(List *p_list) const{ return &Object::_get_property_list; - } + } _FORCE_INLINE_ void (Object::* (_get_notification() const))(int){ return &Object::_notification; - } + } static void get_valid_parents_static(List *p_parents); static void _get_valid_parents_static(List *p_parents); - + void cancel_delete(); @@ -485,7 +485,7 @@ public: void add_change_receptor( Object *p_receptor ); void remove_change_receptor( Object *p_receptor ); - + template T *cast_to() { @@ -500,7 +500,7 @@ public: return NULL; #endif } - + template const T *cast_to() const { @@ -517,11 +517,11 @@ public: } enum { - + NOTIFICATION_POSTINITIALIZE=0, NOTIFICATION_PREDELETE=1 }; - + /* TYPE API */ static void get_inheritance_list_static(List* p_inheritance_list) { p_inheritance_list->push_back("Object"); } @@ -545,7 +545,7 @@ public: return *_type_ptr; } } - + /* IAPI */ // void set(const String& p_name, const Variant& p_value); // Variant get(const String& p_name) const; @@ -554,7 +554,7 @@ public: Variant get(const StringName& p_name, bool *r_valid=NULL) const; void get_property_list(List *p_list,bool p_reversed=false) const; - + bool has_method(const StringName& p_method) const; void get_method_list(List *p_list) const; Variant callv(const StringName& p_method,const Array& p_args); @@ -564,14 +564,14 @@ public: Variant call(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper void call_multilevel(const StringName& p_name, VARIANT_ARG_LIST); // C++ helper - void notification(int p_notification,bool p_reversed=false); + void notification(int p_notification,bool p_reversed=false); //used mainly by script, get and set all INCLUDING string virtual Variant getvar(const Variant& p_key, bool *r_valid=NULL) const; virtual void setvar(const Variant& p_key, const Variant& p_value,bool *r_valid=NULL); /* SCRIPT */ - + void set_script(const RefPtr& p_script); RefPtr get_script() const; @@ -614,14 +614,14 @@ public: StringName tr(const StringName& p_message) const; //translate message (alternative) bool _is_queued_for_deletion; // set to true by SceneTree::queue_delete() - bool is_queued_for_deletion() const; + bool is_queued_for_deletion() const; _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate=p_enable; } _FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; } void clear_internal_resource_paths(); - Object(); + Object(); virtual ~Object(); }; @@ -649,13 +649,13 @@ class ObjectDB { static HashMap instance_checks; static uint32_t instance_counter; -friend class Object; +friend class Object; friend void unregister_core_types(); static void cleanup(); static uint32_t add_instance(Object *p_object); static void remove_instance(Object *p_object); -public: +public: typedef void (*DebugFunc)(Object *p_obj); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 819d0a5cb9..3ee4da5974 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -556,12 +556,16 @@ void make_default_theme() { // GraphNode - Ref graphsb = make_stylebox(graph_node_png,6,24,6,5,16,24,16,5); - Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,16,24,16,5); + Ref graphsb = make_stylebox(graph_node_png,6,24,6,5,3,24,16,5); + Ref graphsbselected = make_stylebox(graph_node_selected_png,6,24,6,5,3,24,16,5); + Ref graphsbdefault = make_stylebox(graph_node_default_png,4,4,4,4,6,4,4,4); + Ref graphsbdeffocus = make_stylebox(graph_node_default_focus_png,4,4,4,4,6,4,4,4); //graphsb->set_expand_margin_size(MARGIN_LEFT,10); //graphsb->set_expand_margin_size(MARGIN_RIGHT,10); t->set_stylebox("frame","GraphNode", graphsb ); t->set_stylebox("selectedframe","GraphNode", graphsbselected ); + t->set_stylebox("defaultframe", "GraphNode", graphsbdefault ); + t->set_stylebox("defaultfocus", "GraphNode", graphsbdeffocus ); t->set_constant("separation","GraphNode", 1 ); t->set_icon("port","GraphNode", make_icon( graph_port_png ) ); t->set_icon("close","GraphNode", make_icon( graph_node_close_png ) ); diff --git a/scene/resources/default_theme/graph_node_default.png b/scene/resources/default_theme/graph_node_default.png new file mode 100644 index 0000000000..ea6ec52828 Binary files /dev/null and b/scene/resources/default_theme/graph_node_default.png differ diff --git a/scene/resources/default_theme/graph_node_default_focus.png b/scene/resources/default_theme/graph_node_default_focus.png new file mode 100644 index 0000000000..b7c38ae481 Binary files /dev/null and b/scene/resources/default_theme/graph_node_default_focus.png differ diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index a00651a0b3..ba818d86b2 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -114,6 +114,16 @@ static const unsigned char graph_node_close_png[]={ }; +static const unsigned char graph_node_default_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x8,0x1a,0x17,0x2e,0xd,0x4c,0xb7,0x38,0x4,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0x85,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x93,0x31,0xa,0x83,0x40,0x14,0x44,0xdf,0xba,0xa5,0x20,0x41,0x30,0x20,0x4,0xab,0x40,0x20,0x7,0xc9,0x69,0xec,0x72,0x4e,0x9b,0xa0,0x1e,0xc1,0x2a,0x42,0x10,0x82,0xbb,0xc5,0x77,0x6d,0x4c,0x11,0x48,0xe3,0xb7,0x49,0xe1,0x6b,0x6,0xa6,0x78,0xd5,0x8c,0x1,0x6e,0x80,0xe1,0x9b,0xb0,0xe4,0xaf,0xde,0x3,0x4f,0xa0,0x3,0x6,0x93,0x67,0xa7,0xc0,0xa,0x44,0x64,0x72,0x7e,0x6c,0x87,0xf7,0xab,0x4,0x1e,0x68,0x38,0x17,0x97,0x90,0xc4,0x87,0xa,0xb8,0xa2,0xe5,0x98,0xe6,0x1,0xb8,0x47,0x5a,0x81,0xb5,0x16,0xa0,0x56,0xb,0x3e,0xec,0x82,0x3f,0x10,0x4c,0x6a,0x81,0x88,0x78,0xc0,0x45,0xda,0x29,0x3b,0x3f,0x36,0x40,0xbf,0xf9,0x4c,0x66,0xeb,0x9d,0x67,0x5c,0x46,0x37,0x51,0xb6,0x55,0x6d,0xc2,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + +static const unsigned char graph_node_default_focus_png[]={ +0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x8,0x1b,0x1,0x9,0x1c,0x5c,0xd5,0x12,0x34,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0xfc,0x49,0x44,0x41,0x54,0x38,0xcb,0xbd,0x93,0x41,0x4a,0x4,0x41,0xc,0x45,0x7f,0xca,0x6a,0x14,0x42,0x2f,0xc4,0x85,0x7,0xf0,0x3c,0xde,0xa2,0xbc,0x41,0xd7,0xa2,0xa1,0x60,0xea,0x60,0xae,0x5c,0xea,0x19,0xdc,0xd7,0x42,0x97,0xe5,0xc,0x12,0xeb,0xbb,0x69,0xa5,0x84,0xe9,0x41,0x1d,0xf1,0x43,0x8,0x84,0xe4,0x2d,0x92,0x1f,0xc1,0x22,0x92,0x2,0xc0,0x2d,0x81,0x2e,0x7f,0xa8,0x75,0xb9,0x89,0x8,0x1,0x40,0x48,0x5e,0x76,0xcd,0xad,0x6b,0x74,0x7b,0xea,0x6,0xe0,0x75,0x9,0x13,0x11,0xca,0x34,0x4d,0xc4,0x37,0x35,0xc,0xc3,0xf3,0x38,0x8e,0xb7,0xf3,0x3c,0xdf,0x0,0xd8,0x1,0x30,0x90,0x4,0x49,0xe4,0x9c,0x11,0x42,0x40,0x29,0x65,0x15,0x50,0x4a,0xb9,0x8,0x21,0x30,0xe7,0x7c,0x47,0x52,0x49,0x9e,0x7c,0x2,0x62,0x8c,0x30,0x33,0xa8,0xea,0x2a,0x40,0x55,0xaf,0xcc,0x4c,0x62,0x8c,0x5b,0x92,0xe7,0x24,0x7,0xd7,0x2d,0x11,0xde,0x7b,0xd4,0x5a,0x57,0x1,0xb5,0xd6,0x47,0xef,0x3d,0x49,0x9e,0x1,0xf0,0x0,0x9c,0xc3,0xef,0xe5,0xf6,0x9d,0xea,0x5f,0x1,0x38,0x16,0xd0,0xfe,0x16,0x20,0x22,0x7,0x3d,0xd0,0x7b,0x41,0x44,0xb6,0x8b,0x2b,0x9b,0xeb,0x6e,0x8c,0x94,0x12,0xcc,0x6c,0x75,0xd8,0xcc,0xc6,0x94,0xd2,0x93,0xaa,0xde,0x2f,0x76,0x6e,0x3f,0xb2,0xb2,0x88,0xec,0x54,0xf5,0x61,0xb3,0xd9,0x5c,0x3,0x78,0x1,0x60,0xc7,0x3c,0x53,0x13,0x91,0x37,0xe9,0x9d,0xd8,0xe9,0xf4,0xc0,0xe2,0xbe,0xbc,0xf3,0x3b,0x49,0xa0,0x89,0xbf,0x71,0xc6,0xcd,0x1c,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 +}; + + static const unsigned char graph_node_selected_png[]={ 0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x40,0x8,0x6,0x0,0x0,0x0,0x13,0x7d,0xf7,0x96,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x7,0x12,0x1,0xc,0x6,0x23,0x98,0xc7,0x50,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x2,0x46,0x49,0x44,0x41,0x54,0x58,0xc3,0xed,0x97,0xcd,0x6a,0x13,0x51,0x14,0xc7,0x7f,0xe7,0xce,0x34,0x49,0xd,0xa6,0xb1,0x2a,0xe2,0x7,0x74,0xa1,0x6e,0x4,0x85,0xe2,0x3,0xb8,0x72,0x21,0xba,0x16,0x5c,0xb9,0x16,0x4,0x7d,0x84,0x3e,0x82,0x82,0xe0,0xda,0x95,0x2f,0x60,0x71,0xe1,0xca,0x7,0xd0,0x82,0xa5,0x6e,0xd4,0x45,0xc1,0x8f,0x4a,0x6c,0x9a,0x46,0x62,0x66,0xa6,0x73,0xef,0x71,0xe1,0x4c,0x92,0x99,0x4c,0x93,0x36,0xdd,0xc9,0xfc,0x37,0x77,0x3e,0xee,0xfd,0xdd,0x73,0xfe,0xf7,0xc,0xcc,0x11,0x86,0x12,0xc0,0x0,0x5e,0x32,0xa,0x59,0x29,0xe0,0x0,0x9b,0x8c,0xca,0xc8,0x24,0x3,0x1c,0x3,0x16,0x81,0xd3,0x40,0x3,0x98,0xcb,0x1,0xf6,0x80,0x2e,0xd0,0x2,0xda,0xc0,0x1f,0xc0,0xa5,0xbb,0xd6,0x81,0x4b,0xb,0xc7,0x9b,0xf,0x6a,0xd5,0xda,0xad,0x4a,0xa5,0x7a,0x81,0x2,0x45,0x51,0xf8,0x35,0x8,0x83,0xd7,0xbb,0xbf,0x3b,0xcf,0x81,0xcf,0x40,0x4f,0x92,0x9d,0x96,0x16,0x9b,0x27,0x9f,0x5c,0x5c,0xba,0x7c,0xfb,0xfe,0xcb,0x3b,0x34,0x2b,0x27,0x8a,0xd6,0xd3,0x89,0x76,0x78,0x71,0xef,0x15,0x5f,0x36,0x3f,0xad,0xb6,0x3b,0xdb,0x8f,0x81,0x4d,0x1,0x6a,0xc0,0xf2,0xd9,0x33,0xe7,0xdf,0xac,0xbc,0x7d,0x54,0xdf,0x73,0x11,0x81,0xed,0x17,0x2,0x6a,0xde,0x3c,0x73,0xa6,0xc2,0xca,0x8d,0xa7,0xbd,0x1f,0x3f,0xbf,0xdd,0x4,0xd6,0xfc,0xc4,0x87,0xba,0xef,0xf9,0xf5,0x6e,0xb4,0xc3,0x24,0xf5,0xe3,0x1e,0x7d,0x7a,0xf8,0x9e,0x5f,0x4f,0xd2,0x96,0x14,0xe0,0x1,0x58,0xb5,0x39,0xdb,0x1d,0x82,0x19,0x5c,0xe7,0xe4,0xa5,0x0,0x4d,0x8f,0x44,0x71,0xa8,0x2a,0x22,0x92,0x81,0x4c,0x92,0x3f,0x7a,0xe3,0xd4,0xe2,0x54,0x41,0xc1,0x13,0xf,0xc5,0xe1,0x54,0x31,0x22,0x8,0xa6,0x10,0x96,0x1,0x58,0x1d,0x4e,0x88,0x35,0x1e,0x79,0x9e,0xd6,0xd0,0x94,0x8,0x54,0xb3,0x93,0x1c,0x8a,0x41,0x6,0x63,0xfa,0x6c,0x5f,0x40,0xe4,0xa2,0xcc,0x4b,0x23,0x32,0xd8,0x37,0x4e,0x52,0x99,0x1c,0x41,0x2e,0x4c,0x9b,0xdd,0x6c,0xec,0xbe,0x20,0x5,0xe5,0xb0,0xca,0x99,0x68,0x93,0x48,0x14,0x41,0x30,0x22,0x3,0x63,0x5,0x41,0x51,0x3c,0x31,0x93,0x8f,0x31,0xf3,0xed,0x6a,0xf6,0x5b,0xfe,0xe7,0x85,0x9b,0x0,0x98,0x52,0x34,0x7,0x2a,0xa4,0xb4,0x74,0x8b,0x4c,0x2d,0x2a,0xa6,0xb1,0x42,0x32,0x8c,0x1b,0x39,0x3c,0x7b,0x37,0xbd,0x90,0xec,0x51,0x52,0x88,0x5d,0x3c,0x36,0x21,0xd,0x39,0x4d,0x4d,0x72,0xc5,0x94,0x1,0xac,0xde,0x7d,0x3f,0xbb,0x89,0xf1,0x9e,0x65,0xf9,0xea,0xf5,0x3,0x2d,0x5a,0x5b,0x7f,0x57,0x1c,0xc1,0x6e,0xb7,0x73,0xe8,0x8,0xc,0x47,0x54,0x9,0x28,0x1,0x25,0xa0,0x4,0x94,0x80,0x12,0x50,0x2,0xfe,0x4b,0x80,0x14,0xf4,0x88,0x87,0x8e,0xc0,0xcd,0xb0,0xd6,0xa5,0x0,0x7,0x4,0xd6,0xda,0xb0,0xe0,0x27,0x6d,0x7c,0x55,0xc,0xd6,0xda,0x10,0x8,0x0,0x67,0x92,0x56,0x76,0x3b,0x8,0xfb,0x1b,0xad,0xf6,0x16,0x93,0x20,0x2e,0x86,0x56,0x7b,0x8b,0x20,0xec,0x6f,0x0,0xdb,0x80,0x4d,0x3b,0xd7,0x5,0xe0,0x5a,0xa3,0xde,0x7c,0x56,0xab,0xce,0x5f,0xf1,0x3c,0xaf,0xd0,0x5c,0x6b,0xad,0xb,0xc2,0xfe,0xc7,0x6e,0xaf,0xf3,0x10,0xf8,0x0,0xec,0xca,0x48,0xb,0xd7,0x0,0xce,0x1,0xa7,0x80,0xea,0x3e,0xcd,0x77,0x8,0xfc,0x2,0xbe,0x27,0x7d,0xb4,0x95,0x9c,0xa1,0x7e,0xda,0xf,0xee,0x93,0x85,0x26,0x29,0xc7,0x33,0x1a,0x3f,0xae,0xbf,0xf0,0x27,0xf6,0x42,0xf6,0xf5,0xfd,0xae,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82 }; diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index 9522667698..fbc76c5143 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -80,12 +80,15 @@ void ShaderGraph::_set_data(const Dictionary &p_data) { ERR_FAIL_COND((conns.size()%3)!=0); for(int j=0;jget().param2; Array conns; - conns.resize(E->get().connections.size()*3); + conns.resize(E->get().connections.size()*3+E->get().defaults.size()*3); int idx2=0; for(Map::Element*F=E->get().connections.front();F;F=F->next()) { @@ -123,6 +126,14 @@ Dictionary ShaderGraph::_get_data() const { conns[idx2+2]=F->get().slot; idx2+=3; } + for(Map::Element*F=E->get().defaults.front();F;F=F->next()) { + + conns[idx2+0]=SLOT_DEFAULT_VALUE; + conns[idx2+1]=F->key(); + conns[idx2+2]=F->get(); + idx2+=3; + } + data[idx+5]=conns; idx+=6; } @@ -164,6 +175,9 @@ void ShaderGraph::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_node_list","shader_type"),&ShaderGraph::_get_node_list); + ObjectTypeDB::bind_method(_MD("default_set_value","shader_type","id","param_id","value"), &ShaderGraph::default_set_value); + ObjectTypeDB::bind_method(_MD("default_get_value","shader_type","id","param_id"), &ShaderGraph::default_get_value); + ObjectTypeDB::bind_method(_MD("scalar_const_node_set_value","shader_type","id","value"),&ShaderGraph::scalar_const_node_set_value); ObjectTypeDB::bind_method(_MD("scalar_const_node_get_value","shader_type","id"),&ShaderGraph::scalar_const_node_set_value); @@ -546,7 +560,7 @@ void ShaderGraph::node_add(ShaderType p_type, NodeType p_node_type,int p_id) { case NODE_RGB_INPUT: {node.param1=_find_unique_name("Color");node.param2=Color();} break; // color uniform (assignable in material) case NODE_XFORM_INPUT: {node.param1=_find_unique_name("XForm"); node.param2=Transform();} break; // mat4 uniform (assignable in material) case NODE_TEXTURE_INPUT: {node.param1=_find_unique_name("Tex"); } break; // texture input (assignable in material) - case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) + case NODE_CUBEMAP_INPUT: {node.param1=_find_unique_name("Cube"); } break; // cubemap input (assignable in material) case NODE_DEFAULT_TEXTURE: {}; break; case NODE_OUTPUT: {} break; // output (shader type dependent) case NODE_COMMENT: {} break; // comment @@ -692,6 +706,18 @@ void ShaderGraph::get_node_connections(ShaderType p_type,List *p_con } } +bool ShaderGraph::is_slot_connected(ShaderGraph::ShaderType p_type, int p_dst_id, int slot_id) +{ + for(const Map::Element *E=shader[p_type].node_map.front();E;E=E->next()) { + for (const Map::Element *F=E->get().connections.front();F;F=F->next()) { + + if (p_dst_id == E->key() && slot_id==F->key()) + return true; + } + } + return false; +} + void ShaderGraph::clear(ShaderType p_type) { @@ -1005,6 +1031,33 @@ ShaderGraph::ScalarFunc ShaderGraph::scalar_func_node_get_function(ShaderType p_ return ScalarFunc(func); } +void ShaderGraph::default_set_value(ShaderGraph::ShaderType p_which, int p_id, int p_param, const Variant &p_value) +{ + ERR_FAIL_INDEX(p_which,3); + ERR_FAIL_COND(!shader[p_which].node_map.has(p_id)); + Node& n = shader[p_which].node_map[p_id]; + if(p_value.get_type()==Variant::NIL) + n.defaults.erase(n.defaults.find(p_param)); + else + n.defaults[p_param]=p_value; + + _request_update(); + +} + +Variant ShaderGraph::default_get_value(ShaderGraph::ShaderType p_which, int p_id, int p_param) +{ + ERR_FAIL_INDEX_V(p_which,3,Variant()); + ERR_FAIL_COND_V(!shader[p_which].node_map.has(p_id),Variant()); + const Node& n = shader[p_which].node_map[p_id]; + + if (!n.defaults.has(p_param)) + return Variant(); + return n.defaults[p_param]; +} + + + void ShaderGraph::vec_func_node_set_function(ShaderType p_type,int p_id,VecFunc p_func){ ERR_FAIL_INDEX(p_type,3); @@ -1030,52 +1083,52 @@ ShaderGraph::VecFunc ShaderGraph::vec_func_node_get_function(ShaderType p_type, void ShaderGraph::color_ramp_node_set_ramp(ShaderType p_type,int p_id,const DVector& p_colors, const DVector& p_offsets){ - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_colors; - n.param2=p_offsets; - _request_update(); + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + ERR_FAIL_COND(p_colors.size()!=p_offsets.size()); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_colors; + n.param2=p_offsets; + _request_update(); } DVector ShaderGraph::color_ramp_node_get_colors(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; } DVector ShaderGraph::color_ramp_node_get_offsets(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param2; + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param2; } void ShaderGraph::curve_map_node_set_points(ShaderType p_type,int p_id,const DVector& p_points) { - ERR_FAIL_INDEX(p_type,3); - ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); - Node& n = shader[p_type].node_map[p_id]; - n.param1=p_points; - _request_update(); + ERR_FAIL_INDEX(p_type,3); + ERR_FAIL_COND(!shader[p_type].node_map.has(p_id)); + Node& n = shader[p_type].node_map[p_id]; + n.param1=p_points; + _request_update(); } DVector ShaderGraph::curve_map_node_get_points(ShaderType p_type,int p_id) const{ - ERR_FAIL_INDEX_V(p_type,3,DVector()); - ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); - const Node& n = shader[p_type].node_map[p_id]; - return n.param1; + ERR_FAIL_INDEX_V(p_type,3,DVector()); + ERR_FAIL_COND_V(!shader[p_type].node_map.has(p_id),DVector()); + const Node& n = shader[p_type].node_map[p_id]; + return n.param1; } @@ -1265,6 +1318,12 @@ Variant ShaderGraph::node_get_state(ShaderType p_type,int p_id) const { s["pos"]=n.pos; s["param1"]=n.param1; s["param2"]=n.param2; + Array keys; + for (Map::Element *E=n.defaults.front();E;E=E->next()) { + keys.append(E->key()); + s[E->key()]=E->get(); + } + s["default_keys"]=keys; return s; } @@ -1277,10 +1336,15 @@ void ShaderGraph::node_set_state(ShaderType p_type,int p_id,const Variant& p_sta ERR_FAIL_COND(!d.has("pos")); ERR_FAIL_COND(!d.has("param1")); ERR_FAIL_COND(!d.has("param2")); + ERR_FAIL_COND(!d.has("default_keys")); + n.pos=d["pos"]; n.param1=d["param1"]; n.param2=d["param2"]; - + Array keys = d["default_keys"]; + for(int i=0;i defaults; int id; mutable int order; // used for sorting int sort_order; @@ -318,6 +320,9 @@ public: VEC_MAX_FUNC }; + void default_set_value(ShaderType p_which,int p_id,int p_param, const Variant& p_value); + Variant default_get_value(ShaderType p_which,int p_id,int p_param); + void vec_func_node_set_function(ShaderType p_which,int p_id,VecFunc p_func); VecFunc vec_func_node_get_function(ShaderType p_which,int p_id) const; @@ -358,6 +363,8 @@ public: void get_node_connections(ShaderType p_which,List *p_connections) const; + bool is_slot_connected(ShaderType p_which,int p_dst_id,int slot_id); + void clear(ShaderType p_which); Variant node_get_state(ShaderType p_type, int p_node) const; diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index b2de10ca20..12a9dce6b7 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -29,6 +29,7 @@ #include "shader_graph_editor_plugin.h" +#include "scene/gui/check_box.h" #include "scene/gui/menu_button.h" #include "scene/gui/panel.h" #include "spatial_editor_plugin.h" @@ -840,6 +841,7 @@ void ShaderGraphView::_xform_input_changed(int p_id, Node *p_button){ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_input_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); ped_popup->popup(); @@ -850,6 +852,7 @@ void ShaderGraphView::_xform_const_changed(int p_id, Node *p_button){ ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::TRANSFORM,graph->xform_const_node_get_value(type,p_id),PROPERTY_HINT_NONE,""); ped_popup->popup(); @@ -879,6 +882,35 @@ void ShaderGraphView::_cube_input_change(int p_id){ void ShaderGraphView::_variant_edited() { + if (edited_def != -1) { + + Variant v = ped_popup->get_variant(); + Variant v2 = graph->default_get_value(type,edited_id,edited_def); + if (v2.get_type() == Variant::NIL) + switch (v.get_type()) { + case Variant::VECTOR3: + v2=Vector3(); + break; + case Variant::REAL: + v2=0.0; + break; + case Variant::TRANSFORM: + v2=Transform(); + break; + case Variant::COLOR: + v2=Color(); + break; + } + UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); + ur->create_action("Change default value"); + ur->add_do_method(graph.ptr(),"default_set_value",type,edited_id,edited_def, v); + ur->add_undo_method(graph.ptr(),"default_set_value",type,edited_id,edited_def, v2); + ur->add_do_method(this,"_update_graph"); + ur->add_undo_method(this,"_update_graph"); + ur->commit_action(); + return; + } + if (graph->node_get_type(type,edited_id)==ShaderGraph::NODE_XFORM_CONST) { UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo(); @@ -1043,6 +1075,7 @@ void ShaderGraphView::_tex_edited(int p_id,Node* p_button) { ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::OBJECT,graph->texture_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"Texture"); } @@ -1052,6 +1085,7 @@ void ShaderGraphView::_cube_edited(int p_id,Node* p_button) { ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); ped_popup->set_size(tb->get_size()); edited_id=p_id; + edited_def=-1; ped_popup->edit(NULL,"",Variant::OBJECT,graph->cubemap_input_node_get_value(type,p_id),PROPERTY_HINT_RESOURCE_TYPE,"CubeMap"); } @@ -1260,6 +1294,97 @@ void ShaderGraphView::_delete_nodes_request() } +void ShaderGraphView::_default_changed(int p_id, Node *p_button, int p_param, int v_type, String p_hint) +{ + ToolButton *tb = p_button->cast_to(); + ped_popup->set_pos(tb->get_global_pos()+Vector2(0,tb->get_size().height)); + ped_popup->set_size(tb->get_size()); + edited_id=p_id; + edited_def=p_param; + Variant::Type vt = (Variant::Type)v_type; + Variant v = graph->default_get_value(type,p_id,edited_def); + int h=PROPERTY_HINT_NONE; + if (v.get_type() == Variant::NIL) + switch (vt) { + case Variant::VECTOR3: + v=Vector3(); + break; + case Variant::REAL: + h=PROPERTY_HINT_RANGE; + v=0.0; + break; + case Variant::TRANSFORM: + v=Transform(); + break; + case Variant::COLOR: + h=PROPERTY_HINT_COLOR_NO_ALPHA; + v=Color(); + break; + } + + ped_popup->edit(NULL,"",vt,v,h,p_hint); + + ped_popup->popup(); +} + +ToolButton *ShaderGraphView::make_label(String text, Variant::Type v_type) { + ToolButton *l = memnew( ToolButton ); + l->set_text(text); + l->set_text_align(ToolButton::ALIGN_LEFT); + l->add_style_override("hover", l->get_stylebox("normal", "ToolButton")); + l->add_style_override("pressed", l->get_stylebox("normal", "ToolButton")); + l->add_style_override("focus", l->get_stylebox("normal", "ToolButton")); + switch (v_type) { + case Variant::REAL: + l->set_icon(ped_popup->get_icon("Real", "EditorIcons")); + break; + case Variant::VECTOR3: + l->set_icon(ped_popup->get_icon("Vector", "EditorIcons")); + break; + case Variant::TRANSFORM: + l->set_icon(ped_popup->get_icon("Matrix", "EditorIcons")); + break; + case Variant::COLOR: + l->set_icon(ped_popup->get_icon("Color", "EditorIcons")); + } + return l; +} + +ToolButton *ShaderGraphView::make_editor(String text,GraphNode* gn,int p_id,int param,Variant::Type v_type, String p_hint) { + ToolButton *edit = memnew( ToolButton ); + edit->set_text(text); + edit->set_text_align(ToolButton::ALIGN_LEFT); + edit->set_flat(false); + edit->add_style_override("normal", gn->get_stylebox("defaultframe", "GraphNode")); + edit->add_style_override("hover", gn->get_stylebox("defaultframe", "GraphNode")); + edit->add_style_override("pressed", gn->get_stylebox("defaultframe", "GraphNode")); + edit->add_style_override("focus", gn->get_stylebox("defaultfocus", "GraphNode")); + edit->connect("pressed",this,"_default_changed",varray(p_id,edit,param,v_type,p_hint)); + + switch (v_type) { + case Variant::REAL: + edit->set_icon(ped_popup->get_icon("Real", "EditorIcons")); + break; + case Variant::VECTOR3: + edit->set_icon(ped_popup->get_icon("Vector", "EditorIcons")); + break; + case Variant::TRANSFORM: + edit->set_icon(ped_popup->get_icon("Matrix", "EditorIcons")); + break; + case Variant::COLOR: + Image icon_color = Image(15,15,false,Image::FORMAT_RGB); + Color c = graph->default_get_value(type,p_id,param); + for (int x=1;x<14;x++) + for (int y=1;y<14;y++) + icon_color.put_pixel(x,y,c); + Ref t; + t.instance(); + t->create_from_image(icon_color); + edit->set_icon(t); + break; + } + return edit; +} void ShaderGraphView::_create_node(int p_id) { @@ -1273,6 +1398,9 @@ void ShaderGraphView::_create_node(int p_id) { Color(0,1,1) }; + const String hint_spin = "-65536,65535,0.001"; + const String hint_slider = "0.0,1.0,0.01,slider"; + switch(graph->node_get_type(type,p_id)) { @@ -1377,7 +1505,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("ScreenTex"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (!graph->is_slot_connected(type,p_id,0)) { + Vector3 v = graph->default_get_value(type, p_id, 0); + hbc->add_child(make_editor("UV: " + v,gn,p_id,0,Variant::VECTOR3)); + } else { + hbc->add_child(make_label("UV",Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("RGB"))); gn->add_child(hbc); @@ -1411,11 +1544,21 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1449,11 +1592,21 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1481,12 +1634,22 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1519,11 +1682,19 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::COLOR)); + } else { + hbc->add_child(make_editor(String("a: "),gn,p_id,0,Variant::COLOR)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::COLOR)); + } else { + gn->add_child(make_editor(String("b: "),gn,p_id,1,Variant::COLOR)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1533,11 +1704,19 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("XFMult"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a",Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("a: edit..."),gn,p_id,0,Variant::TRANSFORM)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b",Variant::TRANSFORM)); + } else { + gn->add_child(make_editor(String("b: edit..."),gn,p_id,1,Variant::TRANSFORM)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],false,0,Color()); @@ -1548,8 +1727,7 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("XFVecMult"); - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); + CheckBox *button = memnew (CheckBox("RotOnly")); button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); @@ -1557,13 +1735,22 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("xf",Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("xf: edit..."),gn,p_id,0,Variant::TRANSFORM)); + } hbc->add_spacer(); Label *l = memnew(Label("out")); l->set_align(Label::ALIGN_RIGHT); hbc->add_child( l); gn->add_child(hbc); - gn->add_child( memnew(Label("vec"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("a: ")+v,gn,p_id,1,Variant::VECTOR3)); + } gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(2,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1574,17 +1761,25 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("XFVecInvMult"); - Button *button = memnew( Button("RotOnly")); - button->set_toggle_mode(true); + CheckBox *button = memnew( CheckBox("RotOnly")); button->set_pressed(graph->xform_vec_mult_node_get_no_translation(type,p_id)); button->connect("toggled",this,"_xform_inv_rev_changed",varray(p_id)); gn->add_child(button); - gn->add_child( memnew(Label("vec"))); + if (graph->is_slot_connected(type, p_id, 0)) { + gn->add_child(make_label("a",Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + gn->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); + if (graph->is_slot_connected(type, p_id, 1)) { + hbc->add_child(make_label("xf", Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("xf: edit..."),gn,p_id,1,Variant::TRANSFORM)); + } hbc->add_spacer(); Label *l = memnew(Label("out")); l->set_align(Label::ALIGN_RIGHT); @@ -1633,7 +1828,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->add_child(ob); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("in", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("in: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); @@ -1668,7 +1868,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("in"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("in", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("in: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("out"))); gn->add_child(hbc); @@ -1679,7 +1884,12 @@ void ShaderGraphView::_create_node(int p_id) { case ShaderGraph::NODE_VEC_LEN: { gn->set_title("VecLength"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("in"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("in", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("in: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("len"))); gn->add_child(hbc); @@ -1692,11 +1902,21 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("DotProduct"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("dp"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1707,7 +1927,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("Vec2Scalar"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("vec"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("vec", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("vec: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("x")); l->set_align(Label::ALIGN_RIGHT); @@ -1732,12 +1957,27 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("Scalar2Vec"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("x"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("x", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("x: ")+Variant(v),gn,p_id,0,Variant::REAL)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("vec"))); gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("y", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("y: ")+Variant(v),gn,p_id,1,Variant::REAL)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("in", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("in: ")+Variant(v),gn,p_id,2,Variant::REAL)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1749,13 +1989,33 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("Vec2XForm"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("x"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("x", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("x: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("xf"))); gn->add_child(hbc); - gn->add_child( memnew(Label("y"))); - gn->add_child( memnew(Label("z"))); - gn->add_child( memnew(Label("ofs"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("y", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("y: ")+v,gn,p_id,1,Variant::VECTOR3)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("z", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("z: ")+v,gn,p_id,2,Variant::VECTOR3)); + } + if (graph->is_slot_connected(type, p_id, 3)) { + gn->add_child(make_label("ofs", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,3); + gn->add_child(make_editor(String("ofs: ")+v,gn,p_id,3,Variant::VECTOR3)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_XFORM,typecol[ShaderGraph::SLOT_TYPE_XFORM]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1769,7 +2029,11 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("xf"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("fx", Variant::TRANSFORM)); + } else { + hbc->add_child(make_editor(String("fx: edit..."),gn,p_id,0,Variant::TRANSFORM)); + } hbc->add_spacer(); Label *l=memnew(Label("x")); l->set_align(Label::ALIGN_RIGHT); @@ -1796,12 +2060,27 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("ScalarInterp"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_spin)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("interp"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+Variant(v),gn,p_id,1,Variant::REAL,hint_spin)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,2,Variant::REAL,hint_slider)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_SCALAR,typecol[ShaderGraph::SLOT_TYPE_SCALAR],false,0,Color()); @@ -1813,12 +2092,27 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("VecInterp"); HBoxContainer *hbc = memnew( HBoxContainer ); - hbc->add_child( memnew(Label("a"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("a", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("a: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); hbc->add_child( memnew(Label("interp"))); gn->add_child(hbc); - gn->add_child( memnew(Label("b"))); - gn->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 1)) { + gn->add_child(make_label("b", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,1); + gn->add_child(make_editor(String("b: ")+v,gn,p_id,1,Variant::VECTOR3)); + } + if (graph->is_slot_connected(type, p_id, 2)) { + gn->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,2); + gn->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,2,Variant::REAL,hint_slider)); + } gn->set_slot(0,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC]); gn->set_slot(1,true,ShaderGraph::SLOT_TYPE_VEC,typecol[ShaderGraph::SLOT_TYPE_VEC],false,0,Color()); @@ -1857,7 +2151,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_slider)); + } hbc->add_spacer(); Label *l=memnew(Label("rgb")); l->set_align(Label::ALIGN_RIGHT); @@ -1902,7 +2201,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("c"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("c", Variant::REAL)); + } else { + float v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("c: ")+Variant(v),gn,p_id,0,Variant::REAL,hint_slider)); + } hbc->add_spacer(); Label *l=memnew(Label("cmap")); l->set_align(Label::ALIGN_RIGHT); @@ -2016,7 +2320,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("UV", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("RGB")); l->set_align(Label::ALIGN_RIGHT); @@ -2047,7 +2356,12 @@ void ShaderGraphView::_create_node(int p_id) { HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("UV", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("RGB")); l->set_align(Label::ALIGN_RIGHT); @@ -2067,7 +2381,12 @@ void ShaderGraphView::_create_node(int p_id) { gn->set_title("CanvasItemTex"); HBoxContainer *hbc = memnew( HBoxContainer ); hbc->add_constant_override("separation",0); - hbc->add_child( memnew(Label("UV"))); + if (graph->is_slot_connected(type, p_id, 0)) { + hbc->add_child(make_label("UV", Variant::VECTOR3)); + } else { + Vector3 v = graph->default_get_value(type,p_id,0); + hbc->add_child(make_editor(String("UV: ")+v,gn,p_id,0,Variant::VECTOR3)); + } hbc->add_spacer(); Label *l=memnew(Label("RGB")); l->set_align(Label::ALIGN_RIGHT); @@ -2091,15 +2410,34 @@ void ShaderGraphView::_create_node(int p_id) { List si; ShaderGraph::get_input_output_node_slot_info(graph->get_mode(),type,&si); + Array colors; + colors.push_back("Color"); + colors.push_back("LightColor"); + Array reals; + reals.push_back("Alpha"); + reals.push_back("NormapMapDepth"); + reals.push_back("LightAlpha"); + reals.push_back("PointSize"); + Array vectors; + vectors.push_back("Normal"); + vectors.push_back("NormalMap"); + vectors.push_back("Vertex"); + vectors.push_back("UV"); + vectors.push_back("Var1"); + vectors.push_back("Var2"); + int idx=0; for (List::Element *E=si.front();E;E=E->next()) { ShaderGraph::SlotInfo& s=E->get(); if (s.dir==ShaderGraph::SLOT_OUT) { - - Label *l= memnew( Label ); - l->set_text(s.name); - l->set_align(Label::ALIGN_LEFT); - gn->add_child(l); + Variant::Type v; + if (colors.find(s.name)>=0) + v=Variant::COLOR; + else if (reals.find(s.name)>=0) + v=Variant::REAL; + else if (vectors.find(s.name)>=0) + v=Variant::VECTOR3; + gn->add_child(make_label(s.name, v)); gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); idx++; } @@ -2256,6 +2594,7 @@ void ShaderGraphView::_bind_methods() { ObjectTypeDB::bind_method("_duplicate_nodes", &ShaderGraphView::_duplicate_nodes); ObjectTypeDB::bind_method("_delete_nodes_request", &ShaderGraphView::_delete_nodes_request); + ObjectTypeDB::bind_method("_default_changed",&ShaderGraphView::_default_changed); ObjectTypeDB::bind_method("_scalar_const_changed",&ShaderGraphView::_scalar_const_changed); ObjectTypeDB::bind_method("_vec_const_changed",&ShaderGraphView::_vec_const_changed); ObjectTypeDB::bind_method("_rgb_const_changed",&ShaderGraphView::_rgb_const_changed); diff --git a/tools/editor/plugins/shader_graph_editor_plugin.h b/tools/editor/plugins/shader_graph_editor_plugin.h index 36443efeb0..800fdf1fea 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.h +++ b/tools/editor/plugins/shader_graph_editor_plugin.h @@ -129,6 +129,7 @@ class ShaderGraphView : public Node { GraphEdit *graph_edit; Ref graph; int edited_id; + int edited_def; ShaderGraph::ShaderType type; @@ -136,6 +137,8 @@ class ShaderGraphView : public Node { void _create_node(int p_id); + ToolButton *make_label(String text, Variant::Type v_type = Variant::NIL); + ToolButton *make_editor(String text, GraphNode* gn, int p_id, int param, Variant::Type type, String p_hint=""); void _connection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); void _disconnection_request(const String& p_from, int p_from_slot,const String& p_to,int p_to_slot); @@ -149,6 +152,9 @@ class ShaderGraphView : public Node { void _duplicate_nodes(Array &p_nodes); void _delete_nodes_request(); + + void _default_changed(int p_id, Node* p_button, int p_param, int v_type, String p_hint); + void _scalar_const_changed(double p_value,int p_id); void _vec_const_changed(double p_value, int p_id, Array p_arr); void _rgb_const_changed(const Color& p_color, int p_id); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index 78a1f0ad15..ae0975c896 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -42,15 +42,15 @@ #include "multi_node_edit.h" void CustomPropertyEditor::_notification(int p_what) { - + if (p_what==NOTIFICATION_DRAW) { - + RID ci = get_canvas_item(); - get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); + get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size())); /* if (v.get_type()==Variant::COLOR) { - + VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( 10,10,60, get_size().height-20 ), v ); }*/ } @@ -211,11 +211,11 @@ void CustomPropertyEditor::_menu_option(int p_which) { } Variant CustomPropertyEditor::get_variant() const { - - return v; + + return v; } String CustomPropertyEditor::get_name() const { - + return name; } @@ -233,9 +233,11 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty inheritors_array.clear(); text_edit->hide(); easing_draw->hide(); - + spinbox->hide(); + slider->hide(); + for (int i=0;ihide(); value_label[i]->hide(); if (i<4) @@ -243,8 +245,8 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } for (int i=0;ihide(); + + action_buttons[i]->hide(); } for(int i=0;i<20;i++) @@ -254,11 +256,49 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty switch(type) { - + case Variant::INT: case Variant::REAL: { - if (hint==PROPERTY_HINT_ALL_FLAGS) { + if (hint==PROPERTY_HINT_RANGE) { + + int c = hint_text.get_slice_count(","); + float min=0,max=100,step=1; + if (c>=1) { + + if (!hint_text.get_slice(",",0).empty()) + min=hint_text.get_slice(",",0).to_double(); + } + if (c>=2) { + + if (!hint_text.get_slice(",",1).empty()) + max=hint_text.get_slice(",",1).to_double(); + } + + if (type==Variant::REAL && c>=3) { + + if (!hint_text.get_slice(",",2).empty()) + step= hint_text.get_slice(",",2).to_double(); + } + + if (c>=4 && hint_text.get_slice(",",3)=="slider") { + slider->set_min(min); + slider->set_max(max); + slider->set_step((type==Variant::REAL) ? step : 1); + slider->set_val(v); + slider->show(); + set_size(Size2(110,30)); + } else { + spinbox->set_min(min); + spinbox->set_max(max); + spinbox->set_step((type==Variant::REAL) ? step : 1); + spinbox->set_val(v); + spinbox->show(); + set_size(Size2(70,35)); + } + + + } else if (hint==PROPERTY_HINT_ALL_FLAGS) { uint32_t flgs = v; for(int i=0;i<2;i++) { @@ -406,7 +446,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[3]->set_text( String::num( r.size.y) ); } break; case Variant::VECTOR3: { - + List names; names.push_back("x"); names.push_back("y"); @@ -418,7 +458,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[2]->set_text( String::num( vec.z) ); } break; case Variant::PLANE: { - + List names; names.push_back("x"); names.push_back("y"); @@ -430,10 +470,10 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[1]->set_text( String::num( plane.normal.y ) ); value_editor[2]->set_text( String::num( plane.normal.z ) ); value_editor[3]->set_text( String::num( plane.d ) ); - + } break; case Variant::QUAT: { - + List names; names.push_back("x"); names.push_back("y"); @@ -448,7 +488,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::_AABB: { - + List names; names.push_back("px"); names.push_back("py"); @@ -457,7 +497,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty names.push_back("sy"); names.push_back("sz"); config_value_editors(6,3,16,names); - + AABB aabb=v; value_editor[0]->set_text( String::num( aabb.pos.x ) ); value_editor[1]->set_text( String::num( aabb.pos.y ) ); @@ -465,7 +505,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[3]->set_text( String::num( aabb.size.x ) ); value_editor[4]->set_text( String::num( aabb.size.y ) ); value_editor[5]->set_text( String::num( aabb.size.z ) ); - + } break; case Variant::MATRIX32: { @@ -486,7 +526,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::MATRIX3: { - + List names; names.push_back("xx"); names.push_back("xy"); @@ -498,17 +538,17 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty names.push_back("zy"); names.push_back("zz"); config_value_editors(9,3,16,names); - + Matrix3 basis=v; for(int i=0;i<9;i++) { - + value_editor[i]->set_text( String::num( basis.elements[i/3][i%3] ) ); } - + } break; case Variant::TRANSFORM: { - - + + List names; names.push_back("xx"); names.push_back("xy"); @@ -523,20 +563,20 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty names.push_back("zz"); names.push_back("zo"); config_value_editors(12,4,16,names); - + Transform tr=v; for(int i=0;i<9;i++) { - + value_editor[(i/3)*4+i%3]->set_text( String::num( tr.basis.elements[i/3][i%3] ) ); } - + value_editor[3]->set_text( String::num( tr.origin.x ) ); value_editor[7]->set_text( String::num( tr.origin.y ) ); value_editor[11]->set_text( String::num( tr.origin.z ) ); - + } break; case Variant::COLOR: { - + color_picker->show(); color_picker->set_edit_alpha(hint!=PROPERTY_HINT_COLOR_NO_ALPHA); @@ -550,13 +590,13 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty float values[4]={c.r,c.g,c.b,c.a}; for (int i=0;i<4;i++) { int y=m+i*h; - + value_editor[i]->show(); - value_label[i]->show(); + value_label[i]->show(); value_label[i]->set_pos(Point2(ofs,y)); scroll[i]->set_min(0); scroll[i]->set_max(1.0); - scroll[i]->set_page(0); + scroll[i]->set_page(0); scroll[i]->set_pos(Point2(ofs+15,y+Math::floor((h-scroll[i]->get_minimum_size().height)/2.0))); scroll[i]->set_val(values[i]); scroll[i]->set_size(Size2(120,1)); @@ -564,30 +604,30 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty value_editor[i]->set_pos(Point2(ofs+140,y)); value_editor[i]->set_size(Size2(40,h)); value_editor[i]->set_text( String::num(values[i],2 )); - + } - + value_label[0]->set_text("R"); value_label[1]->set_text("G"); value_label[2]->set_text("B"); value_label[3]->set_text("A"); - + Size2 new_size = value_editor[3]->get_pos() + value_editor[3]->get_size() + Point2(10,10); set_size( new_size ); */ - + } break; case Variant::IMAGE: { - + List names; names.push_back("New"); names.push_back("Load"); names.push_back("Clear"); config_action_buttons(names); - + } break; case Variant::NODE_PATH: { - + List names; names.push_back("Assign"); names.push_back("Clear"); @@ -595,7 +635,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::OBJECT: { - + if (hint!=PROPERTY_HINT_RESOURCE_TYPE) break; @@ -701,40 +741,40 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty } break; case Variant::INPUT_EVENT: { - - + + } break; case Variant::DICTIONARY: { - - + + } break; case Variant::RAW_ARRAY: { - - + + } break; case Variant::INT_ARRAY: { - - + + } break; case Variant::REAL_ARRAY: { - - + + } break; case Variant::STRING_ARRAY: { - - + + } break; case Variant::VECTOR3_ARRAY: { - - + + } break; case Variant::COLOR_ARRAY: { - - + + } break; default: {} - } - + } + updating=false; return true; } @@ -742,7 +782,7 @@ bool CustomPropertyEditor::edit(Object* p_owner,const String& p_name,Variant::Ty void CustomPropertyEditor::_file_selected(String p_file) { switch(type) { - + case Variant::STRING: { if (hint==PROPERTY_HINT_FILE || hint==PROPERTY_HINT_DIR) { @@ -880,9 +920,9 @@ void CustomPropertyEditor::_node_path_selected(NodePath p_path) { void CustomPropertyEditor::_action_pressed(int p_which) { - if (updating) + if (updating) return; - + switch(type) { case Variant::INT: { @@ -965,7 +1005,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } break; case Variant::NODE_PATH: { - + if (p_which==0) { @@ -976,60 +1016,60 @@ void CustomPropertyEditor::_action_pressed(int p_which) { v=NodePath(); emit_signal("variant_changed"); - } + } } break; case Variant::OBJECT: { - + if (p_which==0) { - + ERR_FAIL_COND( inheritors_array.empty() ); String intype=inheritors_array[0]; - + if (hint==PROPERTY_HINT_RESOURCE_TYPE) { - + Object *obj = ObjectTypeDB::instance(intype); ERR_BREAK( !obj ); Resource *res=obj->cast_to(); ERR_BREAK( !res ); - + v=Ref(res).get_ref_ptr(); emit_signal("variant_changed"); hide(); - + } } else if (p_which==1) { - + file->set_access(EditorFileDialog::ACCESS_RESOURCES); file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List extensions; String type=(hint==PROPERTY_HINT_RESOURCE_TYPE)?hint_text:String(); - + ResourceLoader::get_recognized_extensions_for_type(type,&extensions); file->clear_filters(); for (List::Element *E=extensions.front();E;E=E->next()) { - + file->add_filter("*."+E->get()+" ; "+E->get().to_upper() ); - + } - + file->popup_centered_ratio(); - + } else if (p_which==2) { - + RefPtr RefPtr=v; if (!RefPtr.is_null()) { emit_signal("resource_edit_request"); - hide(); + hide(); } - + } else if (p_which==3) { - - + + v=Variant(); emit_signal("variant_changed"); hide(); @@ -1072,7 +1112,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) { emit_signal("variant_changed"); hide(); } - + } break; case Variant::IMAGE: { @@ -1111,16 +1151,16 @@ void CustomPropertyEditor::_action_pressed(int p_which) { } void CustomPropertyEditor::_scroll_modified(double p_value) { - - if (updating) + + if (updating) return; /* switch(type) { - + case Variant::COLOR: { - + for (int i=0;i<4;i++) { - + value_editor[i]->set_text( String::num(scroll[i]->get_val(),2) ); } Color c; @@ -1145,7 +1185,7 @@ void CustomPropertyEditor::_drag_easing(const InputEvent& p_ev) { float rel = p_ev.mouse_motion.relative_x; if (rel==0) - return; + return; bool flip=hint_text=="attenuation"; @@ -1228,7 +1268,7 @@ void CustomPropertyEditor::_text_edit_changed() { } void CustomPropertyEditor::_modified(String p_string) { - + if (updating) return; updating=true; @@ -1269,17 +1309,17 @@ void CustomPropertyEditor::_modified(String p_string) { } break; case Variant::VECTOR3: { - + Vector3 vec; vec.x=value_editor[0]->get_text().to_double(); vec.y=value_editor[1]->get_text().to_double(); vec.z=value_editor[2]->get_text().to_double(); v=vec; emit_signal("variant_changed"); - + } break; case Variant::PLANE: { - + Plane pl; pl.normal.x=value_editor[0]->get_text().to_double(); pl.normal.y=value_editor[1]->get_text().to_double(); @@ -1287,10 +1327,10 @@ void CustomPropertyEditor::_modified(String p_string) { pl.d=value_editor[3]->get_text().to_double(); v=pl; emit_signal("variant_changed"); - + } break; case Variant::QUAT: { - + Quat q; q.x=value_editor[0]->get_text().to_double(); q.y=value_editor[1]->get_text().to_double(); @@ -1298,10 +1338,10 @@ void CustomPropertyEditor::_modified(String p_string) { q.w=value_editor[3]->get_text().to_double(); v=q; emit_signal("variant_changed"); - + } break; case Variant::_AABB: { - + Vector3 pos; pos.x=value_editor[0]->get_text().to_double(); pos.y=value_editor[1]->get_text().to_double(); @@ -1310,10 +1350,10 @@ void CustomPropertyEditor::_modified(String p_string) { size.x=value_editor[3]->get_text().to_double(); size.y=value_editor[4]->get_text().to_double(); size.z=value_editor[5]->get_text().to_double(); - + v=AABB(pos,size); emit_signal("variant_changed"); - + } break; case Variant::MATRIX32: { @@ -1328,39 +1368,39 @@ void CustomPropertyEditor::_modified(String p_string) { } break; case Variant::MATRIX3: { - + Matrix3 m; for(int i=0;i<9;i++) { - + m.elements[i/3][i%3]=value_editor[i]->get_text().to_double(); } - + v=m; emit_signal("variant_changed"); - + } break; case Variant::TRANSFORM: { - + Matrix3 basis; for(int i=0;i<9;i++) { - + basis.elements[i/3][i%3]=value_editor[(i/3)*4+i%3]->get_text().to_double(); } - + Vector3 origin; origin.x=value_editor[3]->get_text().to_double(); origin.y=value_editor[7]->get_text().to_double(); origin.z=value_editor[11]->get_text().to_double(); - + v=Transform(basis,origin); emit_signal("variant_changed"); - - + + } break; case Variant::COLOR: { /* for (int i=0;i<4;i++) { - + scroll[i]->set_val( value_editor[i]->get_text().to_double() ); } Color c; @@ -1374,51 +1414,57 @@ void CustomPropertyEditor::_modified(String p_string) { */ } break; case Variant::IMAGE: { - - + + } break; case Variant::NODE_PATH: { - - - } break; + + + } break; case Variant::INPUT_EVENT: { - - + + } break; case Variant::DICTIONARY: { - - + + } break; case Variant::RAW_ARRAY: { - - + + } break; case Variant::INT_ARRAY: { - - + + } break; case Variant::REAL_ARRAY: { - - + + } break; case Variant::STRING_ARRAY: { - - + + } break; case Variant::VECTOR3_ARRAY: { - - + + } break; case Variant::COLOR_ARRAY: { - - + + } break; default: {} - } - + } + updating=false; } +void CustomPropertyEditor::_range_modified(double p_value) +{ + v=p_value; + emit_signal("variant_changed"); +} + void CustomPropertyEditor::_focus_enter() { switch(type) { case Variant::REAL: @@ -1475,10 +1521,10 @@ void CustomPropertyEditor::config_action_buttons(const List& p_strings) set_size( Size2( w, m*2+(h+m)*p_strings.size() ) ); for (int i=0;ishow(); - action_buttons[i]->set_text(p_strings[i]); + action_buttons[i]->set_text(p_strings[i]); action_buttons[i]->set_pos( Point2( m, m+i*(h+m) )); action_buttons[i]->set_size( Size2( w-m*2, h ) ); action_buttons[i]->set_flat(true); @@ -1486,29 +1532,29 @@ void CustomPropertyEditor::config_action_buttons(const List& p_strings) action_buttons[i]->hide(); } } - - + + } void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns,int p_label_w,const List& p_strings) { - + int w=80; int h=20; int m=10; - + int rows=((p_amount-1)/p_columns)+1; - + set_size( Size2( m*(1+p_columns)+(w+p_label_w)*p_columns, m*(1+rows)+h*rows ) ); - + for (int i=0;ishow(); value_label[i]->show(); - value_label[i]->set_text(iset_text(iset_pos( Point2( m+p_label_w+c*(w+m+p_label_w), m+r*(h+m) )); value_editor[i]->set_size( Size2( w, h ) ); value_label[i]->set_pos( Point2( m+c*(w+m+p_label_w), m+r*(h+m) ) ); @@ -1518,16 +1564,17 @@ void CustomPropertyEditor::config_value_editors(int p_amount, int p_columns,int value_label[i]->hide(); } } - - - + + + } void CustomPropertyEditor::_bind_methods() { - + ObjectTypeDB::bind_method("_focus_enter", &CustomPropertyEditor::_focus_enter); ObjectTypeDB::bind_method("_focus_exit", &CustomPropertyEditor::_focus_exit); ObjectTypeDB::bind_method("_modified",&CustomPropertyEditor::_modified); + ObjectTypeDB::bind_method("_range_modified", &CustomPropertyEditor::_range_modified); ObjectTypeDB::bind_method("_scroll_modified",&CustomPropertyEditor::_scroll_modified); ObjectTypeDB::bind_method("_action_pressed",&CustomPropertyEditor::_action_pressed); ObjectTypeDB::bind_method("_file_selected",&CustomPropertyEditor::_file_selected); @@ -1544,13 +1591,13 @@ void CustomPropertyEditor::_bind_methods() { ADD_SIGNAL( MethodInfo("resource_edit_request") ); } CustomPropertyEditor::CustomPropertyEditor() { - - + + read_only=false; updating=false; - + for (int i=0;iconnect("focus_enter", this, "_focus_enter"); value_editor[i]->connect("focus_exit", this, "_focus_exit"); } - + for(int i=0;i<4;i++) { - + scroll[i] = memnew( HScrollBar ); scroll[i]->hide(); scroll[i]->set_min(0); scroll[i]->set_max(1.0); - scroll[i]->set_step(0.01); + scroll[i]->set_step(0.01); add_child(scroll[i]); scroll[i]->connect("value_changed", this,"_scroll_modified"); - + } for(int i=0;i<20;i++) { @@ -1595,15 +1642,15 @@ CustomPropertyEditor::CustomPropertyEditor() { text_edit->connect("text_changed",this,"_text_edit_changed"); for (int i=0;ihide(); + action_buttons[i]->hide(); add_child(action_buttons[i]); Vector binds; binds.push_back(i); action_buttons[i]->connect("pressed", this,"_action_pressed",binds); } - + color_picker = memnew( ColorPicker ); add_child(color_picker); color_picker->hide(); @@ -1616,7 +1663,7 @@ CustomPropertyEditor::CustomPropertyEditor() { file = memnew ( EditorFileDialog ); add_child(file); file->hide(); - + file->connect("file_selected", this,"_file_selected"); file->connect("dir_selected", this,"_file_selected"); @@ -1624,12 +1671,12 @@ CustomPropertyEditor::CustomPropertyEditor() { error->set_title("Error!"); add_child(error); //error->get_cancel()->hide(); - + type_button = memnew( MenuButton ); add_child(type_button); type_button->hide(); type_button->get_popup()->connect("item_pressed", this,"_type_create_selected"); - + scene_tree = memnew( SceneTreeDialog ); add_child(scene_tree); @@ -1651,6 +1698,16 @@ CustomPropertyEditor::CustomPropertyEditor() { menu = memnew(PopupMenu); add_child(menu); menu->connect("item_pressed",this,"_menu_option"); + + spinbox = memnew ( SpinBox ); + add_child(spinbox); + spinbox->set_area_as_parent_rect(5); + spinbox->connect("value_changed",this,"_range_modified"); + + slider = memnew ( HSlider ); + add_child(slider); + slider->set_area_as_parent_rect(5); + slider->connect("value_changed",this,"_range_modified"); } @@ -1675,28 +1732,28 @@ Node *PropertyEditor::get_instanced_node() { } TreeItem *PropertyEditor::find_item(TreeItem *p_item,const String& p_name) { - - + + if (!p_item) return NULL; - + String name = p_item->get_metadata(1); - + if (name==p_name) { - + return p_item; } - + TreeItem *c=p_item->get_children(); - + while (c) { - + TreeItem *found = find_item(c,p_name); if (found) return found; c=c->get_next(); } - + return NULL; } @@ -1719,9 +1776,9 @@ void PropertyEditor::_changed_callbacks(Object *p_changed,const String& p_prop) if (p_prop==String()) update_tree_pending=true; else { - + pending[p_prop]=p_prop; - + } } @@ -1733,7 +1790,7 @@ void PropertyEditor::update_property(const String& p_prop) { void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint, const String& p_hint_text) { - + switch( p_type ) { case Variant::BOOL: { @@ -1826,7 +1883,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } break; case Variant::IMAGE: { - + Image img = obj->get( p_name ); if (img.empty()) p_item->set_text(1,"[Image (empty)]"); @@ -1905,7 +1962,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } break; default: {}; } - + } void PropertyEditor::_notification(int p_what) { @@ -1920,10 +1977,10 @@ void PropertyEditor::_notification(int p_what) { edit(NULL); } - + if (p_what==NOTIFICATION_FIXED_PROCESS) { - - + + if (refresh_countdown>0) { refresh_countdown-=get_fixed_process_delta_time(); if (refresh_countdown<=0) { @@ -1933,21 +1990,21 @@ void PropertyEditor::_notification(int p_what) { } changing=true; - + if (update_tree_pending) { update_tree(); update_tree_pending=false; - + } else { - - const String *k=NULL; + + const String *k=NULL; while ((k=pending.next(k))) { - + TreeItem * item = find_item(tree->get_root(),*k); if (!item) continue; - + if (get_instanced_node()) { Dictionary d = get_instanced_node()->get_instance_state(); @@ -1981,15 +2038,15 @@ void PropertyEditor::_notification(int p_what) { } } - Dictionary d=item->get_metadata(0); + Dictionary d=item->get_metadata(0); set_item_text(item,d["type"],d["name"],d["hint"],d["hint_text"]); - } + } } - + pending.clear(); - + changing=false; - + } } @@ -2271,20 +2328,20 @@ void PropertyEditor::update_tree() { d["type"]=(int)p.type; d["hint"]=(int)p.hint; d["hint_text"]=p.hint_string; - + item->set_metadata( 0, d ); item->set_metadata( 1, p.name ); if (draw_red) item->set_custom_color(0,Color(0.8,0.4,0.20)); - + if (p.name==selected_property) { item->select(1); } - + //printf("property %s type %i\n",p.name.ascii().get_data(),p.type); switch( p.type ) { @@ -2365,8 +2422,8 @@ void PropertyEditor::update_tree() { if (p.type==Variant::REAL && c>=3) { step= p.hint_string.get_slice(",",2).to_double(); - } - + } + item->set_range_config(1,min,max,step,p.hint==PROPERTY_HINT_EXP_RANGE); } else if (p.hint==PROPERTY_HINT_ENUM) { @@ -2549,7 +2606,7 @@ void PropertyEditor::update_tree() { } break; case Variant::IMAGE: { - + item->set_cell_mode( 1, TreeItem::CELL_MODE_CUSTOM ); item->set_editable( 1, !read_only ); Image img = obj->get( p.name ); @@ -2558,7 +2615,7 @@ void PropertyEditor::update_tree() { else item->set_text(1,"[Image "+itos(img.get_width())+"x"+itos(img.get_height())+"]"); item->set_icon( 0,get_icon("Image","EditorIcons") ); - + } break; case Variant::NODE_PATH: { @@ -2709,10 +2766,10 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) { void PropertyEditor::_item_edited() { - - TreeItem * item = tree->get_edited(); + + TreeItem * item = tree->get_edited(); Dictionary d = item->get_metadata(0); - + String name=d["name"]; if (tree->get_edited_column()==0) { @@ -2741,12 +2798,12 @@ void PropertyEditor::_item_edited() { int hint= d["hint"]; String hint_text=d["hint_text"]; switch(type) { - + case Variant::NIL: { - - } break; + + } break; case Variant::BOOL: { - + _edit_set(name,item->is_checked(1)); } break; case Variant::INT: @@ -2765,7 +2822,7 @@ void PropertyEditor::_item_edited() { _edit_set(name,item->get_range(1)); } break; case Variant::STRING: { - + if (hint==PROPERTY_HINT_ENUM) { int idx= item->get_range(1); @@ -2783,64 +2840,64 @@ void PropertyEditor::_item_edited() { } } break; // math types - + case Variant::VECTOR3: { - + } break; case Variant::PLANE: { - + } break; case Variant::QUAT: { - + } break; case Variant::_AABB: { - + } break; case Variant::MATRIX3: { - + } break; case Variant::TRANSFORM: { - + } break; - + case Variant::COLOR: { //_edit_set(name,item->get_custom_bg_color(0)); } break; case Variant::IMAGE: { - + } break; case Variant::NODE_PATH: { - + } break; case Variant::INPUT_EVENT: { - + } break; case Variant::DICTIONARY: { - + } break; - + // arrays case Variant::RAW_ARRAY: { - + } break; case Variant::INT_ARRAY: { - + } break; case Variant::REAL_ARRAY: { - + } break; case Variant::STRING_ARRAY: { - + } break; case Variant::VECTOR3_ARRAY: { - + } break; case Variant::COLOR_ARRAY: { - + } break; - - + + }; } @@ -2891,24 +2948,24 @@ void PropertyEditor::_custom_editor_request(bool p_arrow) { } void PropertyEditor::edit(Object* p_object) { - + if (obj==p_object) return; if (obj) { - + obj->remove_change_receptor(this); } obj=p_object; update_tree(); - + if (obj) { - + obj->add_change_receptor(this); } - - + + } void PropertyEditor::_set_range_def(Object *p_item, String prop,float p_frame) { @@ -3003,9 +3060,9 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { void PropertyEditor::_node_removed(Node *p_node) { - + if (p_node==obj) { - + edit(NULL); } } @@ -3065,9 +3122,9 @@ void PropertyEditor::_bind_methods() { ObjectTypeDB::bind_method( "_item_edited",&PropertyEditor::_item_edited); ObjectTypeDB::bind_method( "_item_selected",&PropertyEditor::_item_selected); ObjectTypeDB::bind_method( "_custom_editor_request",&PropertyEditor::_custom_editor_request); - ObjectTypeDB::bind_method( "_custom_editor_edited",&PropertyEditor::_custom_editor_edited); - ObjectTypeDB::bind_method( "_resource_edit_request",&PropertyEditor::_resource_edit_request); - ObjectTypeDB::bind_method( "_node_removed",&PropertyEditor::_node_removed); + ObjectTypeDB::bind_method( "_custom_editor_edited",&PropertyEditor::_custom_editor_edited); + ObjectTypeDB::bind_method( "_resource_edit_request",&PropertyEditor::_resource_edit_request); + ObjectTypeDB::bind_method( "_node_removed",&PropertyEditor::_node_removed); ObjectTypeDB::bind_method( "_edit_button",&PropertyEditor::_edit_button); ObjectTypeDB::bind_method( "_changed_callback",&PropertyEditor::_changed_callbacks); ObjectTypeDB::bind_method( "_draw_flags",&PropertyEditor::_draw_flags); @@ -3127,29 +3184,29 @@ void PropertyEditor::set_show_categories(bool p_show) { } PropertyEditor::PropertyEditor() { - + _prop_edited="property_edited"; _prop_edited_name.push_back(String()); undo_redo=NULL; obj=NULL; changing=false; update_tree_pending=false; - + top_label = memnew( Label ); top_label->set_text("Properties:"); top_label->set_anchor( MARGIN_RIGHT, ANCHOR_END ); top_label->set_begin( Point2( 10,0) ); - top_label->set_end( Point2( 0,12) ); - - add_child(top_label); + top_label->set_end( Point2( 0,12) ); + + add_child(top_label); + - tree = memnew( Tree ); tree->set_anchor( MARGIN_RIGHT, ANCHOR_END ); - tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); + tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END ); tree->set_begin( Point2(0,19 )); tree->set_end( Point2(0,0 )); - + tree->set_columns(2); tree->set_column_expand(0,true); tree->set_column_min_width(0,30); @@ -3157,21 +3214,21 @@ PropertyEditor::PropertyEditor() { tree->set_column_min_width(1,18); //tree->set_hide_root(true); - add_child( tree ); - + add_child( tree ); + tree->connect("item_edited", this,"_item_edited",varray(),CONNECT_DEFERRED); tree->connect("cell_selected", this,"_item_selected"); - + set_fixed_process(true); - + custom_editor = memnew( CustomPropertyEditor ); add_child(custom_editor); - + tree->connect("custom_popup_edited", this,"_custom_editor_request"); tree->connect("button_pressed", this,"_edit_button"); custom_editor->connect("variant_changed", this,"_custom_editor_edited"); custom_editor->connect("resource_edit_request", this,"_resource_edit_request",make_binds(),CONNECT_DEFERRED); - + capitalize_paths=true; autoclear=false; tree->set_column_title(0,"Property"); @@ -3182,7 +3239,7 @@ PropertyEditor::PropertyEditor() { read_only=false; show_categories=false; refresh_countdown=0; - + } diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index de5cac8711..f6e2dfcf50 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -46,9 +46,9 @@ */ class CustomPropertyEditor : public Popup { - + OBJ_TYPE( CustomPropertyEditor, Popup ); - + enum { MAX_VALUE_EDITORS=12, MAX_ACTION_BUTTONS=5, @@ -93,7 +93,8 @@ class CustomPropertyEditor : public Popup { TextEdit *text_edit; bool read_only; Button *checks20[20]; - + SpinBox *spinbox; + HSlider *slider; Control *easing_draw; @@ -105,6 +106,7 @@ class CustomPropertyEditor : public Popup { void _file_selected(String p_file); void _scroll_modified(double p_value); void _modified(String p_string); + void _range_modified(double p_value); void _focus_enter(); void _focus_exit(); void _action_pressed(int p_which); @@ -113,7 +115,7 @@ class CustomPropertyEditor : public Popup { void _color_changed(const Color& p_color); void _draw_easing(); void _menu_option(int p_which); - + void _drag_easing(const InputEvent& p_ev); void _node_path_selected(NodePath p_path); @@ -123,23 +125,23 @@ class CustomPropertyEditor : public Popup { protected: void _notification(int p_what); - static void _bind_methods(); - -public: + static void _bind_methods(); + +public: Variant get_variant() const; String get_name() const; - + void set_read_only(bool p_read_only) { read_only=p_read_only; } bool edit(Object* p_owner,const String& p_name,Variant::Type p_type, const Variant& p_variant,int p_hint,String p_hint_text); - + CustomPropertyEditor(); }; class PropertyEditor : public Control { - + OBJ_TYPE( PropertyEditor, Control ); - + Tree *tree; Label *top_label; //Object *object; @@ -160,27 +162,27 @@ class PropertyEditor : public Control { HashMap pending; String selected_property; - + CustomPropertyEditor *custom_editor; - + void _resource_edit_request(); void _custom_editor_edited(); void _custom_editor_request(bool p_arrow); - + void _item_selected(); void _item_edited(); TreeItem *get_parent_node(String p_path,HashMap& item_paths,TreeItem *root); - + void set_item_text(TreeItem *p_item, int p_type, const String& p_name, int p_hint=PROPERTY_HINT_NONE, const String& p_hint_text=""); - + TreeItem *find_item(TreeItem *p_item,const String& p_name); - - + + virtual void _changed_callback(Object *p_changed,const char * p_what); virtual void _changed_callbacks(Object *p_changed,const String& p_callback); void _edit_button(Object *p_item, int p_column, int p_button); - + void _node_removed(Node *p_node); void _edit_set(const String& p_name, const Variant& p_value); void _draw_flags(Object *ti,const Rect2& p_rect); @@ -191,7 +193,7 @@ class PropertyEditor : public Control { UndoRedo *undo_redo; protected: - + void _notification(int p_what); static void _bind_methods(); public: @@ -217,8 +219,8 @@ public: void set_autoclear(bool p_enable); void set_show_categories(bool p_show); - - PropertyEditor(); + + PropertyEditor(); ~PropertyEditor(); }; -- cgit v1.2.3 From a19a653e2cae50f43b8de5d4ba69170c7d2fa800 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sun, 30 Aug 2015 02:44:49 -0300 Subject: Compile shaders using default values. --- scene/resources/shader_graph.cpp | 87 +++++++++++++++++++--- .../editor/plugins/shader_graph_editor_plugin.cpp | 10 +-- 2 files changed, 79 insertions(+), 18 deletions(-) diff --git a/scene/resources/shader_graph.cpp b/scene/resources/shader_graph.cpp index fbc76c5143..4604c42de1 100644 --- a/scene/resources/shader_graph.cpp +++ b/scene/resources/shader_graph.cpp @@ -1849,17 +1849,17 @@ void ShaderGraph::_update_shader() { Vector inputs; int max = get_node_input_slot_count(get_mode(),ShaderType(i),n->type); for(int k=0;kconnections.has(k)) { - shader[i].error=GRAPH_ERROR_MISSING_CONNECTIONS; - failed=true; - break; + iname="nd"+itos(n->id)+"sl"+itos(k)+"def"; + } else { + iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot); + if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT) { + inputs_used.insert(iname); + } + } - String iname="nd"+itos(n->connections[k].id)+"sl"+itos(n->connections[k].slot); inputs.push_back(iname); - if (node_get_type(ShaderType(i),n->connections[k].id)==NODE_INPUT) { - inputs_used.insert(iname); - } - } if (failed) @@ -2065,6 +2065,31 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectortype,slot)])+" "+("nd"+itos(id)+"sl"+itos(slot))) #define OUTVAR(id,slot) ("nd"+itos(id)+"sl"+itos(slot)) +#define DEF_VEC(slot)\ + if (p_inputs[slot].ends_with("def")){\ + Vector3 v = p_node->defaults[slot];\ + code+=String(typestr[1])+" "+p_inputs[slot]+"=vec3("+v+");\n";\ + } +#define DEF_SCALAR(slot)\ + if (p_inputs[slot].ends_with("def")){\ + double v = p_node->defaults[slot];\ + code+=String(typestr[0])+" "+p_inputs[slot]+"="+rtos(v)+";\n";\ + } +#define DEF_COLOR(slot)\ + if (p_inputs[slot].ends_with("def")){\ + Color col = p_node->defaults[slot];\ + code+=String(typestr[1])+" "+p_inputs[slot]+"=vec3("+rtos(col.r)+","+rtos(col.g)+","+rtos(col.b)+");\n";\ + } +#define DEF_MATRIX(slot) \ + if (p_inputs[slot].ends_with("def")){\ + Transform xf = p_node->defaults[slot]; \ + code+=String(typestr[3])+" "+p_inputs[slot]+"=mat4(\n";\ + code+="\tvec4(vec3("+rtos(xf.basis.get_axis(0).x)+","+rtos(xf.basis.get_axis(0).y)+","+rtos(xf.basis.get_axis(0).z)+"),0),\n";\ + code+="\tvec4(vec3("+rtos(xf.basis.get_axis(1).x)+","+rtos(xf.basis.get_axis(1).y)+","+rtos(xf.basis.get_axis(1).z)+"),0),\n";\ + code+="\tvec4(vec3("+rtos(xf.basis.get_axis(2).x)+","+rtos(xf.basis.get_axis(2).y)+","+rtos(xf.basis.get_axis(2).z)+"),0),\n";\ + code+="\tvec4(vec3("+rtos(xf.origin.x)+","+rtos(xf.origin.y)+","+rtos(xf.origin.z)+"),1)\n";\ + code+=");\n";\ + } switch(p_node->type) { @@ -2101,9 +2126,12 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,0)+"=TIME;\n"; }break; case NODE_SCREEN_TEX: { + DEF_VEC(0); code+=OUTNAME(p_node->id,0)+"=texscreen("+p_inputs[0]+".xy);\n"; }break; case NODE_SCALAR_OP: { + DEF_SCALAR(0); + DEF_SCALAR(1); int op = p_node->param1; String optxt; switch(op) { @@ -2123,6 +2151,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; String optxt; switch(op) { @@ -2140,6 +2170,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; String optxt; switch(op) { @@ -2151,6 +2183,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; static const char*axisn[3]={"x","y","z"}; @@ -2162,7 +2196,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"; - + print_line(OUTNAME(p_node->id,0)+"=abs("+p_inputs[0]+"-"+p_inputs[1]+");\n"); } break; case RGB_OP_DARKEN: { @@ -2233,11 +2267,15 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,0)+"="+p_inputs[0]+"*"+p_inputs[1]+";\n"; }break; case NODE_XFORM_VEC_MULT: { + DEF_MATRIX(0); + DEF_VEC(1); bool no_translation = p_node->param1; if (no_translation) { @@ -2248,6 +2286,8 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; if (no_translation) { code += OUTNAME(p_node->id,0)+"=("+p_inputs[1]+"*vec4("+p_inputs[0]+",0)).xyz;\n"; @@ -2256,6 +2296,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,0)+"=length("+p_inputs[0]+");\n"; }break; case NODE_DOT_PROD: { + DEF_VEC(0); + DEF_VEC(1); code += OUTNAME(p_node->id,0)+"=dot("+p_inputs[1]+","+p_inputs[0]+");\n"; }break; case NODE_VEC_TO_SCALAR: { + DEF_VEC(0); code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n"; code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n"; code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n"; }break; case NODE_SCALAR_TO_VEC: { + DEF_SCALAR(0); + DEF_SCALAR(1); + DEF_SCALAR(2); code += OUTNAME(p_node->id,0)+"=vec3("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+""+");\n"; }break; case NODE_VEC_TO_XFORM: { + DEF_VEC(0); + DEF_VEC(1); + DEF_VEC(2); + DEF_VEC(3); code += OUTNAME(p_node->id,0)+"=xform("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+","+","+p_inputs[3]+");\n"; }break; case NODE_XFORM_TO_VEC: { + DEF_MATRIX(0); code += OUTNAME(p_node->id,0)+"="+p_inputs[0]+".x;\n"; code += OUTNAME(p_node->id,1)+"="+p_inputs[0]+".y;\n"; code += OUTNAME(p_node->id,2)+"="+p_inputs[0]+".z;\n"; code += OUTNAME(p_node->id,3)+"="+p_inputs[0]+".o;\n"; }break; case NODE_SCALAR_INTERP: { + DEF_SCALAR(0); + DEF_SCALAR(1); + DEF_SCALAR(2); code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; }break; case NODE_VEC_INTERP: { + DEF_VEC(0); + DEF_VEC(1); + DEF_SCALAR(2); code += OUTNAME(p_node->id,0)+"=mix("+p_inputs[0]+","+p_inputs[1]+","+p_inputs[2]+");\n"; }break; case NODE_COLOR_RAMP: { + DEF_SCALAR(0); static const int color_ramp_len=512; DVector cramp; @@ -2416,6 +2477,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; float dv=p_node->param2; code +="uniform float "+name+"="+rtos(dv)+";\n"; @@ -2520,6 +2585,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; String rname="rt_read_tex"+itos(p_node->id); code +="uniform texture "+name+";"; @@ -2529,7 +2595,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorparam1; code +="uniform cubemap "+name+";"; String rname="rt_read_tex"+itos(p_node->id); @@ -2538,6 +2604,7 @@ void ShaderGraph::_add_node_code(ShaderType p_type,Node *p_node,const Vectorid,1)+"="+rname+".a;\n"; }break; case NODE_DEFAULT_TEXTURE: { + DEF_VEC(0); if (get_mode()==MODE_CANVAS_ITEM && p_type==SHADER_TYPE_FRAGMENT) { diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 12a9dce6b7..5da287aa69 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -2416,15 +2416,9 @@ void ShaderGraphView::_create_node(int p_id) { Array reals; reals.push_back("Alpha"); reals.push_back("NormapMapDepth"); + reals.push_back("SpecExp"); reals.push_back("LightAlpha"); reals.push_back("PointSize"); - Array vectors; - vectors.push_back("Normal"); - vectors.push_back("NormalMap"); - vectors.push_back("Vertex"); - vectors.push_back("UV"); - vectors.push_back("Var1"); - vectors.push_back("Var2"); int idx=0; for (List::Element *E=si.front();E;E=E->next()) { @@ -2435,7 +2429,7 @@ void ShaderGraphView::_create_node(int p_id) { v=Variant::COLOR; else if (reals.find(s.name)>=0) v=Variant::REAL; - else if (vectors.find(s.name)>=0) + else v=Variant::VECTOR3; gn->add_child(make_label(s.name, v)); gn->set_slot(idx,true,s.type,typecol[s.type],false,0,Color()); -- cgit v1.2.3 From 680402cebf63066abcc93e7e8035e457c6305874 Mon Sep 17 00:00:00 2001 From: Mariano Javier Suligoy Date: Sun, 30 Aug 2015 19:37:23 -0300 Subject: Add missing icons, also make MSVC2010 happy --- scene/gui/spin_box.cpp | 2 +- scene/gui/tree.cpp | 344 ++++++++++----------- .../editor/plugins/shader_graph_editor_plugin.cpp | 15 +- 3 files changed, 184 insertions(+), 177 deletions(-) diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index 2478e3204c..aa20bc6f22 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -125,7 +125,7 @@ void SpinBox::_input_event(const InputEvent& p_event) { if (drag.enabled) { float diff_y = drag.mouse_pos.y - cpos.y; - diff_y=pow(ABS(diff_y),1.8)*SGN(diff_y); + diff_y=pow((float)ABS(diff_y),(float)1.8)*SGN(diff_y); diff_y*=0.1; drag.mouse_pos=cpos; diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 252414cb3e..7941ff3614 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -121,7 +121,7 @@ void TreeItem::set_cell_mode( int p_column, TreeCellMode p_mode ) { c.val=0; c.checked=false; c.icon=Ref(); - c.text=""; + c.text=""; c.icon_max_w=0; _changed_notify(p_column); } @@ -153,9 +153,9 @@ void TreeItem::set_text(int p_column,String p_text) { ERR_FAIL_INDEX( p_column, cells.size() ); cells[p_column].text=p_text; - + if (cells[p_column].mode==TreeItem::CELL_MODE_RANGE) { - + cells[p_column].min=0; cells[p_column].max=p_text.get_slice_count(","); cells[p_column].step=0; @@ -225,7 +225,7 @@ void TreeItem::set_range(int p_column,double p_value) { p_value=cells[p_column].min; if (p_value>cells[p_column].max) p_value=cells[p_column].max; - + cells[p_column].val=p_value; _changed_notify(p_column); @@ -237,7 +237,7 @@ double TreeItem::get_range(int p_column) const { return cells[p_column].val; } - + bool TreeItem::is_range_exponential(int p_column) const { ERR_FAIL_INDEX_V( p_column, cells.size(), false); @@ -304,7 +304,7 @@ void TreeItem::set_collapsed(bool p_collapsed) { if (tree->select_mode==Tree::SELECT_MULTI) { - tree->selected_item=this; + tree->selected_item=this; emit_signal("cell_selected"); } else { @@ -337,11 +337,11 @@ TreeItem *TreeItem::get_prev() { if (!parent || parent->childs==this) return NULL; - + TreeItem *prev = parent->childs; while(prev && prev->next!=this) prev=prev->next; - + return prev; } @@ -636,14 +636,14 @@ void TreeItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_range","column"),&TreeItem::get_range); ObjectTypeDB::bind_method(_MD("set_range_config","column","min","max","step","expr"),&TreeItem::set_range_config,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_range_config","column"),&TreeItem::_get_range_config); - + ObjectTypeDB::bind_method(_MD("set_metadata","column","meta"),&TreeItem::set_metadata); ObjectTypeDB::bind_method(_MD("get_metadata","column"),&TreeItem::get_metadata); ObjectTypeDB::bind_method(_MD("set_custom_draw","column","object","callback"),&TreeItem::set_custom_draw); ObjectTypeDB::bind_method(_MD("set_collapsed","enable"),&TreeItem::set_collapsed); - ObjectTypeDB::bind_method(_MD("is_collapsed"),&TreeItem::is_collapsed); + ObjectTypeDB::bind_method(_MD("is_collapsed"),&TreeItem::is_collapsed); ObjectTypeDB::bind_method(_MD("get_next:TreeItem"),&TreeItem::get_next); ObjectTypeDB::bind_method(_MD("get_prev:TreeItem"),&TreeItem::get_prev); @@ -654,17 +654,17 @@ void TreeItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_prev_visible:TreeItem"),&TreeItem::get_prev_visible); ObjectTypeDB::bind_method(_MD("remove_child:TreeItem","child"),&TreeItem::_remove_child); - + ObjectTypeDB::bind_method(_MD("set_selectable","column","selectable"),&TreeItem::set_selectable); ObjectTypeDB::bind_method(_MD("is_selectable","column"),&TreeItem::is_selectable); ObjectTypeDB::bind_method(_MD("is_selected","column"),&TreeItem::is_selected); ObjectTypeDB::bind_method(_MD("select","column"),&TreeItem::select); ObjectTypeDB::bind_method(_MD("deselect","column"),&TreeItem::deselect); - + ObjectTypeDB::bind_method(_MD("set_editable","column","enabled"),&TreeItem::set_editable); ObjectTypeDB::bind_method(_MD("is_editable","column"),&TreeItem::is_editable); - + ObjectTypeDB::bind_method(_MD("set_custom_color","column","color"),&TreeItem::set_custom_color); ObjectTypeDB::bind_method(_MD("clear_custom_color","column"),&TreeItem::clear_custom_color); @@ -688,7 +688,7 @@ void TreeItem::_bind_methods() { BIND_CONSTANT( CELL_MODE_RANGE ); BIND_CONSTANT( CELL_MODE_ICON ); BIND_CONSTANT( CELL_MODE_CUSTOM ); - + } @@ -774,7 +774,7 @@ void Tree::update_cache() { cache.arrow =get_icon("arrow"); cache.select_arrow =get_icon("select_arrow"); cache.updown=get_icon("updown"); - + cache.font_color=get_color("font_color"); cache.font_color_selected=get_color("font_color_selected"); cache.guide_color=get_color("guide_color"); @@ -802,10 +802,10 @@ int Tree::compute_item_height(TreeItem *p_item) const { if (p_item==root && hide_root) return 0; - + int height=cache.font->get_height(); - + for (int i=0;icells[i].mode) { - + case TreeItem::CELL_MODE_CHECK: { - + int check_icon_h = cache.checked->get_height(); if (height icon = p_item->cells[i].icon; if (!icon.is_null()) { - + Size2i s = p_item->cells[i].get_icon_size(); if (p_item->cells[i].icon_max_w>0 && s.width > p_item->cells[i].icon_max_w ) { s.height=s.height * p_item->cells[i].icon_max_w / s.width; @@ -843,15 +843,15 @@ int Tree::compute_item_height(TreeItem *p_item) const { if (s.height > height ) height=s.height; } - + } break; default: {} } } - - + + height += cache.vseparation; - + return height; } @@ -927,7 +927,7 @@ void Tree::draw_item_text(String p_text,const Ref& p_icon,int p_icon_ma p_rect.size.x-=Math::floor(p_rect.size.y/2); Ref font = cache.font; - + p_rect.pos.y+=Math::floor((p_rect.size.y-font->get_height())/2.0) +font->get_ascent(); font->draw(ci,p_rect.pos,p_text,p_color,p_rect.size.x); } @@ -950,13 +950,13 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& Point2i guide_from; - bool skip=(p_item==root && hide_root); + bool skip=(p_item==root && hide_root); // printf("skip (%p == %p && %i) %i\n",p_item,root,hide_root,skip); if (!skip && (p_pos.y+label_h-cache.offset.y)>0) { - // printf("entering\n"); + // printf("entering\n"); int height=label_h; @@ -965,7 +965,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& if (p_item->childs) { //has childs, draw the guide box Ref arrow; - + if (p_item->collapsed) { arrow=cache.arrow_collapsed; @@ -983,7 +983,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& // if (p_item->get_parent()!=root || !hide_root) Ref font = cache.font; - + int font_ascent=font->get_ascent(); int ofs = p_pos.x + cache.item_margin; @@ -1066,7 +1066,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& } Color col=p_item->cells[i].custom_color?p_item->cells[i].color:get_color( p_item->cells[i].selected?"font_color_selected":"font_color"); - + Point2i text_pos=item_rect.pos; text_pos.y+=Math::floor((item_rect.size.y-font->get_height())/2) + font_ascent; @@ -1104,7 +1104,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& } break; case TreeItem::CELL_MODE_RANGE: { - + if (p_item->cells[i].text!="") { if (!p_item->cells[i].editable) @@ -1128,7 +1128,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& } else { Ref updown = cache.updown; - + String valtext = String::num( p_item->cells[i].val, Math::decimals( p_item->cells[i].step ) ); font->draw( ci, text_pos, valtext, col, item_rect.size.x-updown->get_width()); @@ -1185,7 +1185,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& Rect2i ir=item_rect; ir.size.width-=downarrow->get_width(); draw_item_rect(p_item->cells[i],ir,col); - + Point2i arrow_pos=item_rect.pos; arrow_pos.x+=item_rect.size.x-downarrow->get_width(); arrow_pos.y+=Math::floor(((item_rect.size.y-downarrow->get_height()))/2.0); @@ -1227,7 +1227,7 @@ int Tree::draw_item(const Point2i& p_pos,const Point2& p_draw_ofs, const Size2& children_pos.x+=cache.item_margin; htotal+=label_h; children_pos.y+=htotal; - + } @@ -1272,12 +1272,12 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col continue; if (select_mode==SELECT_ROW) { - + if (p_selected==p_current) { - + if (!c.selected) { - + c.selected=true; selected_item=p_selected; selected_col=0; @@ -1286,26 +1286,26 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col //if (p_col==i) // p_current->selected_signal.call(p_col); } - + } else { - + if (c.selected) { - - c.selected=false; + + c.selected=false; //p_current->deselected_signal.call(p_col); } - + } - + } else if (select_mode==SELECT_SINGLE || select_mode==SELECT_MULTI) { - + if (!r_in_range && &selected_cell==&c) { - + if (!selected_cell.selected) { - + selected_cell.selected=true; - + selected_item=p_selected; selected_col=i; @@ -1321,7 +1321,7 @@ void Tree::select_single_item(TreeItem *p_selected,TreeItem *p_current,int p_col } } else { - + if (r_in_range && *r_in_range) { @@ -1372,7 +1372,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ int item_h=compute_item_height( p_item )+cache.vseparation; bool skip=(p_item==root && hide_root); - + if (!skip && p_pos.y checked = cache.checked; bring_up_editor=false; //checkboxes are not edited with editor if (x>=0 && x<= checked->get_width()+cache.hseparation ) { - + p_item->set_checked(col,!c.checked); - item_edited(col,p_item); + item_edited(col,p_item); click_handled=true; //p_item->edited_signal.call(col); } @@ -1549,37 +1549,37 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ //} bring_up_editor=false; } else { - + Ref updown = cache.updown; - - + + if (x >= (col_width-item_h/2)) { - + /* touching the combo */ bool up=p_pos.y < (item_h /2); - + if (p_button==BUTTON_LEFT) { p_item->set_range( col, c.val + (up?1.0:-1.0) * c.step ); - - item_edited(col,p_item); + + item_edited(col,p_item); } else if (p_button==BUTTON_RIGHT) { - + p_item->set_range( col, (up?c.max:c.min) ); - item_edited(col,p_item); + item_edited(col,p_item); } else if (p_button==BUTTON_WHEEL_UP) { - + p_item->set_range( col, c.val + c.step ); - item_edited(col,p_item); + item_edited(col,p_item); } else if (p_button==BUTTON_WHEEL_DOWN) { - + p_item->set_range( col, c.val - c.step ); - item_edited(col,p_item); + item_edited(col,p_item); } - - //p_item->edited_signal.call(col); + + //p_item->edited_signal.call(col); bring_up_editor=false; - - + + } else { editor_text=String::num( p_item->cells[col].val, Math::decimals( p_item->cells[col].step ) ); @@ -1587,7 +1587,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ if (select_mode==SELECT_MULTI && get_tree()->get_last_event_id() == focus_in_id) bring_up_editor=false; - } + } } click_handled=true; @@ -1598,12 +1598,12 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } break; case TreeItem::CELL_MODE_CUSTOM: { edited_item=p_item; - edited_col=col; + edited_col=col; custom_popup_rect=Rect2i(get_global_pos() + Point2i(col_ofs,_get_title_button_height()+y_ofs+item_h-cache.offset.y), Size2(get_column_width(col),item_h)); emit_signal("custom_popup_edited",((bool)(x >= (col_width-item_h/2)))); bring_up_editor=false; - item_edited(col,p_item); + item_edited(col,p_item); click_handled=true; return -1; } break; @@ -1615,7 +1615,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ - click_handled=true; + click_handled=true; popup_edited_item=p_item; popup_edited_item_col=col; @@ -1627,14 +1627,14 @@ int Tree::propagate_mouse_event(const Point2i &p_pos,int x_ofs,int y_ofs,bool p_ } else { Point2i new_pos=p_pos; - + if (!skip) { x_ofs+=cache.item_margin; //new_pos.x-=cache.item_margin; y_ofs+=item_h; new_pos.y-=item_h; } - + if (!p_item->collapsed) { /* if not collapsed, check the childs */ @@ -1697,7 +1697,7 @@ void Tree::text_editor_enter(String p_text) { default: { ERR_FAIL(); } } - item_edited(popup_edited_item_col,popup_edited_item); + item_edited(popup_edited_item_col,popup_edited_item); update(); } @@ -1725,19 +1725,19 @@ void Tree::popup_select(int p_option) { if (popup_edited_item_col<0 || popup_edited_item_col>columns.size()) return; - + popup_edited_item->cells[popup_edited_item_col].val=p_option; //popup_edited_item->edited_signal.call( popup_edited_item_col ); update(); - item_edited(popup_edited_item_col,popup_edited_item); + item_edited(popup_edited_item_col,popup_edited_item); } void Tree::_input_event(InputEvent p_event) { - + switch (p_event.type) { - + case InputEvent::KEY: { if (!p_event.key.pressed) @@ -2070,7 +2070,7 @@ void Tree::_input_event(InputEvent p_event) { TreeItem::Cell &c=popup_edited_item->cells[popup_edited_item_col]; float diff_y = -b.relative_y; - diff_y=pow(ABS(diff_y),1.8)*SGN(diff_y); + diff_y=pow((float)ABS(diff_y),(float)1.8)*SGN(diff_y); diff_y*=0.1; range_drag_base=CLAMP(range_drag_base + c.step * diff_y, c.min, c.max); @@ -2091,12 +2091,12 @@ void Tree::_input_event(InputEvent p_event) { } } break; case InputEvent::MOUSE_BUTTON: { - + if (cache.font.is_null()) // avoid a strange case that may fuckup stuff update_cache(); - const InputEventMouseButton& b=p_event.mouse_button; + const InputEventMouseButton& b=p_event.mouse_button; if (!b.pressed) { @@ -2160,7 +2160,7 @@ void Tree::_input_event(InputEvent p_event) { switch(b.button_index) { case BUTTON_LEFT: { Ref bg = cache.bg; - + Point2 pos = Point2(b.x,b.y) - bg->get_offset(); cache.click_type=Cache::CLICK_NONE; if (show_column_titles) { @@ -2222,18 +2222,18 @@ void Tree::_input_event(InputEvent p_event) { } break; - case BUTTON_WHEEL_UP: { + case BUTTON_WHEEL_UP: { v_scroll->set_val( v_scroll->get_val()-v_scroll->get_page()/8 ); } break; case BUTTON_WHEEL_DOWN: { - + v_scroll->set_val( v_scroll->get_val()+v_scroll->get_page()/8 ); } break; } - + } break; } - + } @@ -2331,10 +2331,10 @@ Size2 Tree::get_internal_min_size() const { if (root) size.height+=get_item_height(root); for (int i=0;iget_combined_minimum_size(); - + v_scroll->set_begin( Point2(size.width - vmin.width , cache.bg->get_margin(MARGIN_TOP)) ); v_scroll->set_end( Point2(size.width, size.height-cache.bg->get_margin(MARGIN_TOP)-cache.bg->get_margin(MARGIN_BOTTOM)) ); - + h_scroll->set_begin( Point2( 0, size.height - hmin.height) ); h_scroll->set_end( Point2(size.width-vmin.width, size.height) ); - - + + Size2 min = get_internal_min_size(); - + if (min.height < size.height - hmin.height) { - + v_scroll->hide(); cache.offset.y=0; } else { - + v_scroll->show(); v_scroll->set_max(min.height); v_scroll->set_page(size.height - hmin.height - tbh); cache.offset.y=v_scroll->get_val(); } - + if (min.width < size.width - vmin.width) { - + h_scroll->hide(); cache.offset.x=0; } else { - + h_scroll->show(); h_scroll->set_max(min.width); h_scroll->set_page(size.width - vmin.width); cache.offset.x=h_scroll->get_val(); - } + } } @@ -2464,16 +2464,16 @@ void Tree::_notification(int p_what) { } if (p_what==NOTIFICATION_DRAW) { - + update_cache(); update_scrollbars(); - RID ci = get_canvas_item(); - + RID ci = get_canvas_item(); + VisualServer::get_singleton()->canvas_item_set_clip(ci,true); - + Ref bg = cache.bg; Ref bg_focus = get_stylebox("bg_focus"); - + Point2 draw_ofs; draw_ofs+=bg->get_offset(); Size2 draw_size=get_size()-bg->get_minimum_size(); @@ -2491,7 +2491,7 @@ void Tree::_notification(int p_what) { draw_size.y-=tbh; if (root) { - + draw_item( Point2(),draw_ofs,draw_size,root); @@ -2502,10 +2502,10 @@ void Tree::_notification(int p_what) { // int size_y=exposed.size.height-bg->get_minimum_size().height; for (int i=0;i<(columns.size()-1-1);i++) { - + ofs+=get_column_width(i); //get_painter()->draw_fill_rect( Point2(ofs+cache.hseparation/2, from_y), Size2( 1, size_y ),color( COLOR_TREE_GRID) ); - } + } if (show_column_titles) { @@ -2605,7 +2605,7 @@ TreeItem* Tree::get_last_item() { } void Tree::item_edited(int p_column,TreeItem *p_item) { - + edited_item=p_item; edited_col=p_column; emit_signal("item_edited"); @@ -2613,14 +2613,14 @@ void Tree::item_edited(int p_column,TreeItem *p_item) { void Tree::item_changed(int p_column,TreeItem *p_item) { - update(); + update(); } void Tree::item_selected(int p_column,TreeItem *p_item) { if (select_mode==SELECT_MULTI) { - + if (!p_item->cells[p_column].selectable) return; @@ -2636,16 +2636,16 @@ void Tree::item_selected(int p_column,TreeItem *p_item) { void Tree::item_deselected(int p_column,TreeItem *p_item) { if (select_mode==SELECT_MULTI) { - + p_item->cells[p_column].selected=false; - } + } update(); } void Tree::set_select_mode(SelectMode p_mode) { - select_mode=p_mode; + select_mode=p_mode; } void Tree::clear() { @@ -2675,15 +2675,15 @@ void Tree::set_hide_root(bool p_enabled) { - hide_root=p_enabled; - update(); + hide_root=p_enabled; + update(); } void Tree::set_column_min_width(int p_column,int p_min_width) { ERR_FAIL_INDEX(p_column,columns.size()); - + if (p_min_width<1) return; columns[p_column].min_width=p_min_width; @@ -2693,8 +2693,8 @@ void Tree::set_column_min_width(int p_column,int p_min_width) { void Tree::set_column_expand(int p_column,bool p_expand) { ERR_FAIL_INDEX(p_column,columns.size()); - - columns[p_column].expand=p_expand; + + columns[p_column].expand=p_expand; update(); } @@ -2709,78 +2709,78 @@ int Tree::get_selected_column() const { } TreeItem *Tree::get_edited() const { - + return edited_item; } int Tree::get_edited_column() const { - + return edited_col; } TreeItem* Tree::get_next_selected( TreeItem* p_item) { - + //if (!p_item) // return NULL; if (!root) - return NULL; - + return NULL; + while(true) { - - + + if (!p_item) { p_item=root; } else { - + if (p_item->childs) { - + p_item=p_item->childs; - + } else if (p_item->next) { - - p_item=p_item->next; + + p_item=p_item->next; } else { - + while(!p_item->next) { - + p_item=p_item->parent; if (p_item==NULL) return NULL; } - + p_item=p_item->next; } - + } - + for (int i=0;icells[i].selected) return p_item; } - + return NULL; } int Tree::get_column_width(int p_column) const { - + ERR_FAIL_INDEX_V(p_column,columns.size(),-1); - - + + if (!columns[p_column].expand) return columns[p_column].min_width; - + Ref bg = cache.bg; - + int expand_area=get_size().width-(bg->get_margin(MARGIN_LEFT)+bg->get_margin(MARGIN_RIGHT)); - + if (v_scroll->is_visible()) expand_area-=v_scroll->get_combined_minimum_size().width; - + int expanding_columns=0; int expanding_total=0; - + for (int i=0;icells.resize( columns.size() ); - + TreeItem *c = p_item->get_children(); while(c) { - + propagate_set_columns(c); c=c->get_next(); } } void Tree::set_columns(int p_columns) { - + ERR_FAIL_COND(p_columns<1); ERR_FAIL_COND(blocked>0); columns.resize(p_columns); - + if (root) propagate_set_columns(root); if (selected_col>=p_columns) @@ -2824,17 +2824,17 @@ void Tree::set_columns(int p_columns) { } int Tree::get_columns() const { - + return columns.size(); } void Tree::_scroll_moved(float) { - + update(); } Rect2 Tree::get_custom_popup_rect() const { - + return custom_popup_rect; } @@ -3116,7 +3116,7 @@ bool Tree::can_cursor_exit_tree() const { void Tree::_bind_methods() { - + ObjectTypeDB::bind_method(_MD("_input_event"),&Tree::_input_event); ObjectTypeDB::bind_method(_MD("_popup_select"),&Tree::popup_select); ObjectTypeDB::bind_method(_MD("_text_editor_enter"),&Tree::text_editor_enter); @@ -3140,7 +3140,7 @@ void Tree::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_columns","amount"),&Tree::set_columns); ObjectTypeDB::bind_method(_MD("get_columns"),&Tree::get_columns); - + ObjectTypeDB::bind_method(_MD("get_edited:TreeItem"),&Tree::get_edited); ObjectTypeDB::bind_method(_MD("get_edited_column"),&Tree::get_edited_column); ObjectTypeDB::bind_method(_MD("get_custom_popup_rect"),&Tree::get_custom_popup_rect); @@ -3179,7 +3179,7 @@ Tree::Tree() { edited_item=NULL; selected_col=-1; edited_col=-1; - + hide_root=false; select_mode=SELECT_SINGLE; root=0; @@ -3187,8 +3187,8 @@ Tree::Tree() { popup_edited_item=NULL; text_editor=NULL; set_focus_mode(FOCUS_ALL); - - + + popup_menu = memnew( PopupMenu ); popup_menu->hide(); add_child(popup_menu); @@ -3204,7 +3204,7 @@ Tree::Tree() { h_scroll = memnew( HScrollBar ); v_scroll = memnew( VScrollBar ); - + add_child(h_scroll); add_child(v_scroll); @@ -3250,6 +3250,6 @@ Tree::~Tree() { if (root) { memdelete( root ); } - + } diff --git a/tools/editor/plugins/shader_graph_editor_plugin.cpp b/tools/editor/plugins/shader_graph_editor_plugin.cpp index 5da287aa69..1997b268a7 100644 --- a/tools/editor/plugins/shader_graph_editor_plugin.cpp +++ b/tools/editor/plugins/shader_graph_editor_plugin.cpp @@ -2413,12 +2413,21 @@ void ShaderGraphView::_create_node(int p_id) { Array colors; colors.push_back("Color"); colors.push_back("LightColor"); + colors.push_back("Light"); + colors.push_back("Diffuse"); + colors.push_back("Specular"); + colors.push_back("Emmision"); Array reals; reals.push_back("Alpha"); - reals.push_back("NormapMapDepth"); + reals.push_back("DiffuseAlpha"); + reals.push_back("NormalMapDepth"); reals.push_back("SpecExp"); + reals.push_back("Glow"); + reals.push_back("ShadeParam"); + reals.push_back("SpecularExp"); reals.push_back("LightAlpha"); reals.push_back("PointSize"); + reals.push_back("Discard"); int idx=0; for (List::Element *E=si.front();E;E=E->next()) { @@ -2739,10 +2748,8 @@ const char* ShaderGraphEditor::node_names[ShaderGraph::NODE_TYPE_MAX]={ ShaderGraphEditor::ShaderGraphEditor(bool p_2d) { _2d=p_2d; - HBoxContainer *hbc = memnew( HBoxContainer ); popup = memnew( PopupMenu ); - hbc->add_child(popup); - add_child(hbc); + add_child(popup); tabs = memnew(TabContainer); -- cgit v1.2.3 From e8223a90e43fe6315c8f45ce914cab0b6ae6923b Mon Sep 17 00:00:00 2001 From: Cesar Verdes Date: Sun, 6 Sep 2015 12:17:50 -0300 Subject: Ignore some extension of files created by Visual Studio 2013 --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 613eff442a..08213c1e5c 100644 --- a/.gitignore +++ b/.gitignore @@ -73,6 +73,8 @@ platform/android/libs/play_licensing/gen/* *.suo *.user *.sln.docstates +*.sln +*.vcxproj* # Build results [Dd]ebug/ -- cgit v1.2.3 From 930cb97c7d5e1bd4946564c97ea636ca3ed81963 Mon Sep 17 00:00:00 2001 From: firefly2442 Date: Tue, 8 Sep 2015 22:48:22 -0500 Subject: hide opened menu when click on menu button --- scene/gui/popup_menu.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index e706053592..5afe2ed704 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -323,8 +323,10 @@ void PopupMenu::_input_event(const InputEvent &p_event) { invalidated_click=false; break; } - if (over<0 || items[over].separator || items[over].disabled) + if (over<0 || items[over].separator || items[over].disabled) { + hide(); break; //non-activable + } if (items[over].submenu!="") { -- cgit v1.2.3 From 0e60b959cd19e6971ee19851a340c13d28f228c1 Mon Sep 17 00:00:00 2001 From: firefly2442 Date: Wed, 9 Sep 2015 02:55:47 -0500 Subject: Fix absolute paths used in doxygen, ignore generated documentation in Git --- .gitignore | 5 ++++- Doxyfile | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 613eff442a..66cf235f67 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,9 @@ tools/editor/editor_icons.cpp make.bat log.txt +# Doxygen generated documentation +doc/doxygen/* + # Javascript specific *.bc @@ -282,4 +285,4 @@ cscope.in.out cscope.po.out godot.creator.* -projects/ \ No newline at end of file +projects/ diff --git a/Doxyfile b/Doxyfile index c32a1bf195..4268ed8c7d 100644 --- a/Doxyfile +++ b/Doxyfile @@ -51,14 +51,14 @@ PROJECT_BRIEF = "Game Engine MIT" # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. -PROJECT_LOGO = E:/development/godot/logo_small.png +PROJECT_LOGO = ./logo_small.png # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. -OUTPUT_DIRECTORY = E:/development/godot/doxygen +OUTPUT_DIRECTORY = ./doc/doxygen/ # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and @@ -768,7 +768,7 @@ WARN_LOGFILE = # spaces. # Note: If this tag is empty the current directory is searched. -INPUT = E:/development/godot +INPUT = ./core/ ./main/ ./scene/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -- cgit v1.2.3 From 867c95223d0e972b88aa26a3d8dc40530b02f09b Mon Sep 17 00:00:00 2001 From: masoud bh Date: Wed, 16 Sep 2015 16:14:38 +0430 Subject: Fix android build script some fixes for android build script. remove armv6,x86 options and add "android_arch" option for select compiler architecture (armv7,armv6,x86)(default armv7). add architecture suffix for output files and you can compile for several architecture simultaneously. example: libgodot.android.opt.debug.armv7.so libgodot.android.opt.debug.armv7.neon.so libgodot.android.opt.debug.armv6.so libgodot.android.opt.debug.x86.so now we can enable/disable neon on armv7 with "android_neon" option (default enable). add "NDK_TARGET_X86" option for select toolchain to use for the NDK x86 (default x86-4.8). change inputs model for "ndk_platform" option (default android-15). fix armv7 ccflags. with this patch, must put libgodot_android.so file in specific architecture folder: armv7 (default): /libs/armeabi-v7a/ armv6: /libs/armeabi/ x86: /libs/x86/ --- drivers/webp/dsp/dsp.h | 2 +- platform/android/detect.py | 91 +++++++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 35 deletions(-) diff --git a/drivers/webp/dsp/dsp.h b/drivers/webp/dsp/dsp.h index afe30413c6..fd686a8532 100644 --- a/drivers/webp/dsp/dsp.h +++ b/drivers/webp/dsp/dsp.h @@ -29,7 +29,7 @@ extern "C" { #define WEBP_USE_SSE2 #endif -#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__) +#if defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_NEON__) #define WEBP_ANDROID_NEON // Android targets that might support NEON #endif diff --git a/platform/android/detect.py b/platform/android/detect.py index fce1fe3ed6..b29f4899cd 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -20,15 +20,14 @@ def can_build(): def get_opts(): return [ - ('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)), - ('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"), - #android 2.3 - ('ndk_platform', 'compile for platform: (2.2,2.3)',"2.2"), - ('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"), - ('android_stl','enable STL support in android port (for modules)','no'), - ('armv6','compile for older phones running arm v6 (instead of v7+neon+smp)','no'), - ('x86','Xompile for Android-x86','no') - + ('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)), + ('NDK_TOOLCHAIN', 'toolchain to use for the NDK',"arm-eabi-4.4.0"), + ('NDK_TARGET', 'toolchain to use for the NDK',"arm-linux-androideabi-4.8"), + ('NDK_TARGET_X86', 'toolchain to use for the NDK x86',"x86-4.8"), + ('ndk_platform', 'compile for platform: (android- , example: android-15)',"android-15"), + ('android_arch', 'select compiler architecture: (armv7/armv6/x86)',"armv7"), + ('android_neon','enable neon (armv7 only)',"yes"), + ('android_stl','enable STL support in android port (for modules)',"no") ] def get_flags(): @@ -94,8 +93,13 @@ def configure(env): env['SPAWN'] = mySpawn - if env['x86']=='yes': - env['NDK_TARGET']='x86-4.8' + ndk_platform=env['ndk_platform'] + + if env['android_arch'] not in ['armv7','armv6','x86']: + env['android_arch']='armv7' + + if env['android_arch']=='x86': + env['NDK_TARGET']=env['NDK_TARGET_X86'] if env['PLATFORM'] == 'win32': import methods @@ -103,22 +107,28 @@ def configure(env): #env['SPAWN'] = methods.win32_spawn env['SHLIBSUFFIX'] = '.so' -# env.android_source_modules.append("../libs/apk_expansion") + #env.android_source_modules.append("../libs/apk_expansion") env.android_source_modules.append("../libs/google_play_services") env.android_source_modules.append("../libs/downloader_library") env.android_source_modules.append("../libs/play_licensing") - - ndk_platform="" - - ndk_platform="android-15" - print("Godot Android!!!!!") + neon_text="" + if env["android_arch"]=="armv7" and env['android_neon']=='yes': + neon_text=" (with neon)" + print("Godot Android!!!!! ("+env['android_arch']+")"+neon_text) env.Append(CPPPATH=['#platform/android']) - if env['x86']=='yes': - env.extra_suffix=".x86" - + if env['android_arch']=='x86': + env.extra_suffix=".x86"+env.extra_suffix + elif env['android_arch']=='armv6': + env.extra_suffix=".armv6"+env.extra_suffix + elif env["android_arch"]=="armv7": + if env['android_neon']=='yes': + env.extra_suffix=".armv7.neon"+env.extra_suffix + else: + env.extra_suffix=".armv7"+env.extra_suffix + gcc_path=env["ANDROID_NDK_ROOT"]+"/toolchains/"+env["NDK_TARGET"]+"/prebuilt/"; import os @@ -136,7 +146,7 @@ def configure(env): env['ENV']['PATH'] = gcc_path+":"+env['ENV']['PATH'] - if env['x86']=='yes': + if env['android_arch']=='x86': env['CC'] = gcc_path+'/i686-linux-android-gcc' env['CXX'] = gcc_path+'/i686-linux-android-g++' env['AR'] = gcc_path+"/i686-linux-android-ar" @@ -149,7 +159,7 @@ def configure(env): env['RANLIB'] = gcc_path+"/arm-linux-androideabi-ranlib" env['AS'] = gcc_path+"/arm-linux-androideabi-as" - if env['x86']=='yes': + if env['android_arch']=='x86': env['ARCH'] = 'arch-x86' else: env['ARCH'] = 'arch-arm' @@ -163,12 +173,18 @@ def configure(env): env.Append(CPPPATH=[gcc_include]) # env['CCFLAGS'] = string.split('-DNO_THREADS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__ -Wno-psabi -march=armv5te -mtune=xscale -msoft-float -fno-exceptions -mthumb -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED ') - if env['x86']=='yes': + env['neon_enabled']=False + if env['android_arch']=='x86': env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__GLIBC__ -Wno-psabi -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED') - elif env["armv6"]!="no": + elif env["android_arch"]=="armv6": env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_6__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=vfp -mfloat-abi=softfp -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED') - else: - env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__GLIBC__ -Wno-psabi -march=armv6 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED') + elif env["android_arch"]=="armv7": + env['CCFLAGS'] = string.split('-DNO_STATVFS -MMD -MP -MF -fpic -ffunction-sections -funwind-tables -fstack-protector -fvisibility=hidden -D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -D__GLIBC__ -Wno-psabi -march=armv7-a -mfloat-abi=softfp -ftree-vectorize -funsafe-math-optimizations -fno-strict-aliasing -DANDROID -Wa,--noexecstack -DGLES2_ENABLED') + if env['android_neon']=='yes': + env['neon_enabled']=True + env.Append(CCFLAGS=['-mfpu=neon','-D__ARM_NEON__']) + else: + env.Append(CCFLAGS=['-mfpu=vfpv3-d16']) env.Append(LDPATH=[ld_path]) env.Append(LIBS=['OpenSLES']) @@ -192,17 +208,22 @@ def configure(env): env.Append(CCFLAGS=['-D_DEBUG', '-g1', '-Wall', '-O0', '-DDEBUG_ENABLED']) env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']) - if env["armv6"] == "no" and env['x86'] != 'yes': - env['neon_enabled']=True - env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL','-DMPC_FIXED_POINT']) # env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED','-DMPC_FIXED_POINT']) if (env['android_stl']=='yes'): #env.Append(CCFLAGS=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/system/include"]) - env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/include"]) - env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi/include"]) - env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.4.3/libs/armeabi"]) + env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/include"]) + if env['android_arch']=='x86': + env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86/include"]) + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/x86"]) + elif env['android_arch']=='armv6': + env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi/include"]) + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi"]) + elif env["android_arch"]=="armv7": + env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include"]) + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a"]) + env.Append(LIBS=["gnustl_static","supc++"]) env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"]) @@ -213,10 +234,12 @@ def configure(env): env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/include"]) env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cpufeatures"]) - if env['x86']=='yes': + if env['android_arch']=='x86': env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/x86"]) - else: + elif env["android_arch"]=="armv6": env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi"]) + elif env["android_arch"]=="armv7": + env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"]+"/sources/cxx-stl/gabi++/libs/armeabi-v7a"]) env.Append(LIBS=['gabi++_static']) env.Append(CCFLAGS=["-fno-exceptions",'-DNO_SAFE_CAST']) -- cgit v1.2.3 From 9d540afd1cd3eeb7cc318d2761bae778d32218be Mon Sep 17 00:00:00 2001 From: masoud bh Date: Wed, 16 Sep 2015 16:28:01 +0430 Subject: android remove "gen" folder from git. --- .../vending/expansion/downloader/BuildConfig.java | 6 -- .../android/vending/expansion/downloader/R.java | 73 ---------------------- 2 files changed, 79 deletions(-) delete mode 100644 platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java delete mode 100644 platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java diff --git a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java b/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java deleted file mode 100644 index da9d06e63c..0000000000 --- a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java +++ /dev/null @@ -1,6 +0,0 @@ -/** Automatically generated file. DO NOT MODIFY */ -package com.android.vending.expansion.downloader; - -public final class BuildConfig { - public final static boolean DEBUG = false; -} \ No newline at end of file diff --git a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java b/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java deleted file mode 100644 index 330aed1856..0000000000 --- a/platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/R.java +++ /dev/null @@ -1,73 +0,0 @@ -/* AUTO-GENERATED FILE. DO NOT MODIFY. - * - * This class was automatically generated by the - * aapt tool from the resource data it found. It - * should not be modified by hand. - */ - -package com.android.vending.expansion.downloader; - -public final class R { - public static final class attr { - } - public static final class drawable { - public static int notify_panel_notification_icon_bg=0x7f020000; - } - public static final class id { - public static int appIcon=0x7f060001; - public static int description=0x7f060007; - public static int notificationLayout=0x7f060000; - public static int progress_bar=0x7f060006; - public static int progress_bar_frame=0x7f060005; - public static int progress_text=0x7f060002; - public static int time_remaining=0x7f060004; - public static int title=0x7f060003; - } - public static final class layout { - public static int status_bar_ongoing_event_progress_bar=0x7f030000; - } - public static final class string { - public static int kilobytes_per_second=0x7f040014; - /** When a download completes, a notification is displayed, and this - string is used to indicate that the download successfully completed. - Note that such a download could have been initiated by a variety of - applications, including (but not limited to) the browser, an email - application, a content marketplace. - */ - public static int notification_download_complete=0x7f040000; - /** When a download completes, a notification is displayed, and this - string is used to indicate that the download failed. - Note that such a download could have been initiated by a variety of - applications, including (but not limited to) the browser, an email - application, a content marketplace. - */ - public static int notification_download_failed=0x7f040001; - public static int state_completed=0x7f040007; - public static int state_connecting=0x7f040005; - public static int state_downloading=0x7f040006; - public static int state_failed=0x7f040013; - public static int state_failed_cancelled=0x7f040012; - public static int state_failed_fetching_url=0x7f040010; - public static int state_failed_sdcard_full=0x7f040011; - public static int state_failed_unlicensed=0x7f04000f; - public static int state_fetching_url=0x7f040004; - public static int state_idle=0x7f040003; - public static int state_paused_by_request=0x7f04000a; - public static int state_paused_network_setup_failure=0x7f040009; - public static int state_paused_network_unavailable=0x7f040008; - public static int state_paused_roaming=0x7f04000d; - public static int state_paused_sdcard_unavailable=0x7f04000e; - public static int state_paused_wifi_disabled=0x7f04000c; - public static int state_paused_wifi_unavailable=0x7f04000b; - public static int state_unknown=0x7f040002; - public static int time_remaining=0x7f040015; - public static int time_remaining_notification=0x7f040016; - } - public static final class style { - public static int ButtonBackground=0x7f050003; - public static int NotificationText=0x7f050000; - public static int NotificationTextSecondary=0x7f050004; - public static int NotificationTextShadow=0x7f050001; - public static int NotificationTitle=0x7f050002; - } -} -- cgit v1.2.3 From afbb6c064c88d743d8a7d04b5dbfb4b0b1b2db7f Mon Sep 17 00:00:00 2001 From: firefly2442 Date: Wed, 16 Sep 2015 15:35:30 -0500 Subject: ran cppcheck, found unused variables --- core/io/marshalls.cpp | 3 --- core/io/resource_loader.cpp | 2 -- platform/android/audio_driver_opensl.cpp | 3 +-- platform/android/cpu-features.c | 2 +- platform/bb10/audio_driver_bb10.cpp | 1 - servers/physics/body_pair_sw.cpp | 1 - servers/visual/visual_server_raster.cpp | 1 - tools/editor/io_plugins/editor_sample_import_plugin.cpp | 2 +- 8 files changed, 3 insertions(+), 12 deletions(-) diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index b0d24abfe3..1e76e2b4b2 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -299,10 +299,8 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * ERR_FAIL_COND_V(len<12,ERR_INVALID_DATA); Vector names; Vector subnames; - bool absolute; StringName prop; - int i=0; uint32_t namecount=strlen&=0x7FFFFFFF; uint32_t subnamecount = decode_uint32(buf+4); uint32_t flags = decode_uint32(buf+8); @@ -391,7 +389,6 @@ Error decode_variant(Variant& r_variant,const uint8_t *p_buffer, int p_len,int * ie.type=decode_uint32(&buf[0]); ie.device=decode_uint32(&buf[4]); - uint32_t len = decode_uint32(&buf[8])-12; if (r_len) (*r_len)+=12; diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index 1e014480f4..3862790b02 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -231,14 +231,12 @@ Ref ResourceLoader::load_import_metadata(const String &p local_path = Globals::get_singleton()->localize_path(p_path); String extension=p_path.extension(); - bool found=false; Ref ret; for (int i=0;irecognize(extension)) continue; - found=true; Error err = loader[i]->load_import_metadata(local_path,ret); if (err==OK) diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index a08bc8943c..761bef27aa 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -236,13 +236,12 @@ void AudioDriverOpenSL::start(){ ERR_FAIL_COND( res !=SL_RESULT_SUCCESS ); /* Initialize arrays required[] and iidArray[] */ - int i; SLboolean required[MAX_NUMBER_INTERFACES]; SLInterfaceID iidArray[MAX_NUMBER_INTERFACES]; #if 0 - for (i=0; iget_shape(p_shape_A)->get_support(p_xform_A.basis.xform(mnormal).normalized()); Vector3 from = p_xform_A.xform(s); Vector3 to = from + motion; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 155d10d85a..3ae7cfeaf8 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -5211,7 +5211,6 @@ void VisualServerRaster::_light_instance_update_lispsm_shadow(Instance *p_light, AABB proj_space_aabb; - float max_d,min_d; { diff --git a/tools/editor/io_plugins/editor_sample_import_plugin.cpp b/tools/editor/io_plugins/editor_sample_import_plugin.cpp index 9491f957c3..9298b35b3b 100644 --- a/tools/editor/io_plugins/editor_sample_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_sample_import_plugin.cpp @@ -710,7 +710,7 @@ void EditorSampleImportPlugin::_compress_ima_adpcm(const Vector& p_data,D *(out++) =0; for (i=0;i Date: Wed, 16 Sep 2015 16:43:00 -0500 Subject: add missing physics unit test to --help listing in main.cpp --- bin/tests/test_main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/bin/tests/test_main.cpp b/bin/tests/test_main.cpp index 3dba347e39..5567145aa0 100644 --- a/bin/tests/test_main.cpp +++ b/bin/tests/test_main.cpp @@ -61,6 +61,7 @@ const char ** tests_get_names() { "gui", "io", "shaderlang", + "physics", NULL }; -- cgit v1.2.3 From 3c466afb68eeca60f09950680d7eec58471b6882 Mon Sep 17 00:00:00 2001 From: masoud bh Date: Thu, 17 Sep 2015 05:19:43 +0430 Subject: Fix X11 Editor Boot Splash --- platform/x11/os_x11.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 51f4392eb4..ef808c54fb 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -892,7 +892,13 @@ void OS_X11::set_window_maximized(bool p_enabled) { XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); + XWindowAttributes xwa; + XGetWindowAttributes(x11_display,DefaultRootWindow(x11_display),&xwa); + current_videomode.width = xwa.width; + current_videomode.height = xwa.height; + maximized = p_enabled; + visual_server->init(); } bool OS_X11::is_window_maximized() const { -- cgit v1.2.3 From 4210d5e4594fcf80bc121bccc916d411663d02bc Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Fri, 18 Sep 2015 12:52:34 +0300 Subject: Remove of use_exclude_ctrl_bones option use_exclude_ctrl_bones option is not implemented. This option is supposed to filter-out unneeded skeleton bones. This option was never implemented (in repository) and confuses users that feature exists. This commit removes this option as this option implementation is not happenning any time soon and claim it exists confuses users into thinking the feature is supported. Closes #2476 --- tools/export/blender25/io_scene_dae/__init__.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/export/blender25/io_scene_dae/__init__.py b/tools/export/blender25/io_scene_dae/__init__.py index 5b561673c5..182ec21e63 100644 --- a/tools/export/blender25/io_scene_dae/__init__.py +++ b/tools/export/blender25/io_scene_dae/__init__.py @@ -104,11 +104,6 @@ class ExportDAE(bpy.types.Operator, ExportHelper): description="Export only objects on the active layers.", default=True, ) - use_exclude_ctrl_bones = BoolProperty( - name="Exclude Control Bones", - description="Exclude skeleton bones with names that begin with 'ctrl'.", - default=True, - ) use_anim = BoolProperty( name="Export Animation", description="Export keyframe animation", -- cgit v1.2.3 From 1d45c9a04c4c755843a162b872e59680fcb9c94d Mon Sep 17 00:00:00 2001 From: George Marques Date: Sun, 20 Sep 2015 16:17:30 -0300 Subject: Make dict2inst set internal members of instance Fix #2490 --- modules/gdscript/gd_functions.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/gdscript/gd_functions.cpp b/modules/gdscript/gd_functions.cpp index 37ddb2bc41..6f51ac5312 100644 --- a/modules/gdscript/gd_functions.cpp +++ b/modules/gdscript/gd_functions.cpp @@ -904,6 +904,15 @@ void GDFunctions::call(Function p_func,const Variant **p_args,int p_arg_count,Va r_ret = gdscr->_new(NULL,0,r_error); + GDInstance *ins = static_cast(static_cast(r_ret)->get_script_instance()); + Ref gd_ref = ins->get_script(); + + for(Map::Element *E = gd_ref->member_indices.front(); E; E = E->next()) { + if(d.has(E->key())) { + ins->members[E->get().index] = d[E->key()]; + } + } + } break; case HASH: { -- cgit v1.2.3 From d9583f8a7283bbeac1dceaf0885bba297961432e Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Thu, 24 Sep 2015 10:17:06 +0300 Subject: Add missing \n to world_wrap. Close #2516 The issue was that world_wrap would skip over newlines, without adding them to the output. --- core/ustring.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ustring.cpp b/core/ustring.cpp index e5419effcb..7582376fe0 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -3066,7 +3066,7 @@ String String::world_wrap(int p_chars_per_line) const { } else if (operator[](i)==' ' || operator[](i)=='\t') { last_space=i; } else if (operator[](i)=='\n') { - ret+=substr(from,i-from); + ret+=substr(from,i-from)+"\n"; from=i+1; last_space=-1; } -- cgit v1.2.3 From 2a90186a8e07ef280e438788802a01c5976e57fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20P=C3=A9rez?= Date: Thu, 24 Sep 2015 12:03:06 +0200 Subject: Disable filters for tilemap in 2D Platformer demo Fixes #2452 --- demos/2d/platformer/tiles_demo.png.flags | 1 + 1 file changed, 1 insertion(+) create mode 100644 demos/2d/platformer/tiles_demo.png.flags diff --git a/demos/2d/platformer/tiles_demo.png.flags b/demos/2d/platformer/tiles_demo.png.flags new file mode 100644 index 0000000000..efb2b8ce5f --- /dev/null +++ b/demos/2d/platformer/tiles_demo.png.flags @@ -0,0 +1 @@ +filter=false -- cgit v1.2.3 From 721d9a58c79fc6c82b6cbe27707ed10fb25ad9ba Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Fri, 25 Sep 2015 18:41:42 +0300 Subject: Removed a badly listed parameter from funcRef::call_func... --- core/func_ref.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/core/func_ref.cpp b/core/func_ref.cpp index 0e43112de8..fe09ae01af 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -32,7 +32,6 @@ void FuncRef::_bind_methods() { { MethodInfo mi; mi.name="call"; - mi.arguments.push_back( PropertyInfo( Variant::STRING, "method")); Vector defargs; for(int i=0;i<10;i++) { mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); -- cgit v1.2.3 From a0dffc2942c5893e0204cc8d2b85c860c58ef2fe Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Fri, 25 Sep 2015 18:51:04 +0300 Subject: Update mi.name --- core/func_ref.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/func_ref.cpp b/core/func_ref.cpp index fe09ae01af..66962710bd 100644 --- a/core/func_ref.cpp +++ b/core/func_ref.cpp @@ -31,7 +31,7 @@ void FuncRef::_bind_methods() { { MethodInfo mi; - mi.name="call"; + mi.name="call_func"; Vector defargs; for(int i=0;i<10;i++) { mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i))); -- cgit v1.2.3 From f95f099eb2337c9e367bb46f61324b709c42973e Mon Sep 17 00:00:00 2001 From: Jorge Araya Navarro Date: Sat, 26 Sep 2015 23:55:00 -0600 Subject: Adding the new Python file This script works different compared to the other, for instance, it requires Python 3.x to run. It also have more sophisticate flags to run. And finally this file conforms to PEP8. This script is not finished yet, though. --- tools/docdump/makedocs.py | 184 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 tools/docdump/makedocs.py diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py new file mode 100644 index 0000000000..d11515e94a --- /dev/null +++ b/tools/docdump/makedocs.py @@ -0,0 +1,184 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +# +# makedocs.py: Generate documentation for Open Project Wiki +# +# Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. +# +# Contributor: Jorge Araya Navarro +# + +import re +import argparse +import logging +from os import path +from itertools import izip_longest +from xml.etree import ElementTree + +logging.basicConfig(level=logging.INFO) + + +def getxmlfloc(): + """ Returns the supposed location of the XML file + """ + filepath = path.dirname(path.abspath(__file__)) + return path.join(filepath, "class_list.xml") + + +def sortkey(c): + """ Symbols are first, letters second + """ + if "_" == c.attrib["name"][0]: + return True + else: + return c.attrib["name"] + + +def toOP(text): + """ Convert commands in text to Open Project commands + """ + # We are going to do something very complicated with all HTML commands + # sadly, some commands are embedded inside other commands, so some steps + # are needed before converting some commands to Textile markup + groups = re.finditer((r'\[html (?P/?\w+/?)(\]| |=)?(\]| |=)?(?P\w+)?(\]| |=)?(?P"[^"]+")?/?\]'), text) + alignstr = "" + for group in groups: + gd = group.groupdict() + if gd["command"] == "br/": + text = text.replace(group.group(0), "\n\n", 1) + elif gd["command"] == "div": + if gd["value"] == '"center"': + alignstr = "{display:block; margin-left:auto; margin-right:auto;}" + elif gd["value"] == '"left"': + alignstr = "<" + elif gd["value"] == '"right"': + alignstr = ">" + text = text.replace(group.group(0), "\n\n", 1) + elif gd["command"] == "/div": + alignstr = "" + text = text.replace(group.group(0), "\n\n", 1) + elif gd["command"] == "img": + text = text.replace(group.group(0), "!{align}{src}!".format( + align=alignstr, src=gd["value"].strip('"')), 1) + elif gd["command"] == "b" or gd["command"] == "/b": + text = text.replace(group.group(0), "*", 1) + elif gd["command"] == "i" or gd["command"] == "/i": + text = text.replace(group.group(0), "_", 1) + elif gd["command"] == "u" or gd["command"] == "/u": + text = text.replace(group.group(0), "+", 1) + # TODO: Process other non-html commands + return text + "\n\n" + +desc = "Generates documentation from a XML file to different markup languages" + +parser = argparse.ArgumentParser(description=desc) +parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(), + help="Input XML file, default: {}".format(getxmlfloc())) +parser.add_argument("--output-dir", dest="outputdir", required=True, + help="Output directory for generated files") +# TODO: add an option for outputting different markup formats + +args = parser.parse_args() +# Let's check if the file and output directory exists +if not path.isfile(args.xmlfp): + logging.critical("File not found: {}".format(args.xmlfp)) + exit(1) +elif not path.isdir(args.outputdir): + logging.critical("Path does not exist: {}".format(args.outputdir)) + exit(1) + +# Let's begin +tree = ElementTree.parse(args.xmlfp) +root = tree.getroot() + +# Check version attribute exists in +if "version" not in root.attrib: + logging.critical("'s version attribute missing") + exit(1) + +version = root.attrib["version"] +classes = sorted(root, key=sortkey) +# first column is always longer, second column of classes should be shorter +zclasses = izip_longest(classes[:len(classes) / 2 + 1], + classes[len(classes) / 2 + 1:], + fillvalue="") + +# We write the class_list file and also each class file at once +with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: + # Write header of table + fcl.write("|^.\n") + fcl.write("|_. Index symbol |_. Class name " + "|_. Index symbol |_. Class name |\n") + fcl.write("|-.\n") + + indexletterl = "" + indexletterr = "" + for gdclassl, gdclassr in zclasses: + # write a row # + # write the index symbol column, left + if indexletterl != gdclassl.attrib["name"][0]: + indexletterl = gdclassl.attrib["name"][0] + fcl.write("| *{}* |".format(indexletterl.upper())) + else: + # empty cell + fcl.write("| |") + # write the class name column, left + fcl.write("\"{name}({title})\":/class_{link}".format( + name=gdclassl.attrib["name"], + title="Go to page of class " + gdclassl.attrib["name"], + link="class_" + gdclassl.attrib["name"].lower())) + + # write the index symbol column, right + if isinstance(gdclassr, ElementTree.Element): + if indexletterr != gdclassr.attrib["name"][0]: + indexletterr = gdclassr.attrib["name"][0] + fcl.write("| *{}* |".format(indexletterr.upper())) + else: + # empty cell + fcl.write("| |") + # We are dealing with an empty string + else: + # two empty cell + fcl.write("| | |\n") + # We won't get the name of the class since there is no ElementTree + # object for the right side of the tuple, so we iterate the next + # tuple instead + continue + + # write the class name column (if any), right + fcl.write("\"{name}({title})\":/{link} |\n".format( + name=gdclassr.attrib["name"], + title="Go to page of class " + gdclassr.attrib["name"], + link=gdclassr.attrib["name"].lower())) + + # row written # + # now, let's write each class page for each class + for gdclass in [gdclassl, gdclassr]: + if not isinstance(ElementTree.Element, gdclass): + continue + + classname = gdclass.attrib["name"] + with open(path.join(args.outputdir, "{}.txt".format( + classname.lower())), "wb") as clsf: + # First level header with the name of the class + clsf.write("h1. {}\n".format(classname)) + # lay the attributes + if "inherits" in gdclass.attrib: + inh = gdclass.attrib["inherits"].strip() + clsf.write( + "*Inherits:* \"{name}({title})\":/class_{link}\n". + format( + name=classname, + title="Go to page of class " + classname, + link=classname.lower())) + if "category" in gdclass.attrib: + clsf.write("*Category:* {}". + format(gdclass.attrib["category"].strip())) + # lay child nodes + for gdchild in gdclass.iter(): + if gdchild.tag == "brief_description": + clsf.write("h2. Brief Description\n") + clsf.write(toOP(gdchild.text.strip())) + # convert commands in text -- cgit v1.2.3 From 7a008afc67cbbdc26e38477621856c04193280b6 Mon Sep 17 00:00:00 2001 From: Jorge Araya Navarro Date: Sun, 27 Sep 2015 19:25:13 -0600 Subject: XML to Open Project Wiki implemented --- tools/docdump/makedocs.py | 264 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 229 insertions(+), 35 deletions(-) diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py index d11515e94a..81469eed9c 100644 --- a/tools/docdump/makedocs.py +++ b/tools/docdump/makedocs.py @@ -9,16 +9,47 @@ # Contributor: Jorge Araya Navarro # +# IMPORTANT NOTICE: +# If you are going to modify anything from this file, please be sure to follow +# the Style Guide for Python Code or often called "PEP8". To do this +# automagically just install autopep8: +# +# $ sudo pip3 install autopep8 +# +# and run: +# +# $ autopep8 makedocs.py +# +# Before committing your changes. Also be sure to delete any trailing +# whitespace you may left. +# +# TODO: +# * Refactor code. Refactor strings. +# * Adapt this script for generating content in other markup formats like +# DokuWiki, Markdown, etc. +# * Because people will translate class_list.xml, we should implement +# internalization. +# +# Also check other TODO entries in this script for more information on what is +# left to do. + import re import argparse import logging from os import path -from itertools import izip_longest +from itertools import zip_longest from xml.etree import ElementTree +# add an option to change the verbosity logging.basicConfig(level=logging.INFO) +def tb(string): + """ Return a byte representation of a string + """ + return bytes(string, "UTF-8") + + def getxmlfloc(): """ Returns the supposed location of the XML file """ @@ -30,7 +61,7 @@ def sortkey(c): """ Symbols are first, letters second """ if "_" == c.attrib["name"][0]: - return True + return "A" else: return c.attrib["name"] @@ -50,7 +81,8 @@ def toOP(text): text = text.replace(group.group(0), "\n\n", 1) elif gd["command"] == "div": if gd["value"] == '"center"': - alignstr = "{display:block; margin-left:auto; margin-right:auto;}" + alignstr = ("{display:block; margin-left:auto;" + " margin-right:auto;}") elif gd["value"] == '"left"': alignstr = "<" elif gd["value"] == '"right"': @@ -68,9 +100,115 @@ def toOP(text): text = text.replace(group.group(0), "_", 1) elif gd["command"] == "u" or gd["command"] == "/u": text = text.replace(group.group(0), "+", 1) - # TODO: Process other non-html commands + # Process other non-html commands + groups = re.finditer((r'\[method ((?P[aA0-zZ9_]+)(?:\.))' + r'?(?P[aA0-zZ9_]+)\]'), text) + for group in groups: + gd = group.groupdict() + if gd["class"]: + replacewith = ("\"{gclass}.{method}(Go " + "to page {gclass}, section {method})\"" + ":/class_{lkclass}#{lkmethod}". + format(gclass=gd["class"], + method=gd["method"], + lkclass=gd["class"].lower(), + lkmethod=gd["method"].lower())) + else: + # The method is located in the same wiki page + replacewith = ("\"{method}(Jump to method" + " {method})\":#{lkmethod}". + format(method=gd["method"], + lkmethod=gd["method"].lower())) + + text = text.replace(group.group(0), replacewith, 1) + # Finally, [Classes] are around brackets, make them direct links + groups = re.finditer(r'\[(?P[az0-AZ0_]+)\]', text) + for group in groups: + gd = group.groupdict() + replacewith = ("\"{gclass}(Go to page of class" + " {gclass})\":/class_{lkclass}". + format(gclass=gd["class"], + lkclass=gd["class"].lower())) + text = text.replace(group.group(0), replacewith, 1) + return text + "\n\n" + +def mkfn(node, is_signal=False): + """ Return a string containing a unsorted item for a function + """ + finalstr = "" + name = node.attrib["name"] + rtype = node.find("return") + if rtype: + rtype = rtype.attrib["type"] + else: + rtype = "void" + # write the return type and the function name first + finalstr += "* " + # return type + if not is_signal: + if rtype != "void": + finalstr += " \"{rtype}({title})\":/class_{link} ".format( + rtype=rtype, + title="Go to page of class " + rtype, + link=rtype.lower()) + else: + finalstr += " void " + + # function name + if not is_signal: + finalstr += "\"*{funcname}*({title})\":#{link} ( ".format( + funcname=name, + title="Jump to description for node " + name, + link=name.lower()) + else: + # Signals have no description + finalstr += "*{funcname}* (".format(funcname=name) + # loop for the arguments of the function, if any + args = [] + for arg in sorted( + node.iter(tag="argument"), + key=lambda a: int(a.attrib["index"])): + + twd = "{type} {name}={default}" + tnd = "{type} {name}" + tlk = ("\"*{cls}*(Go to page of class {cls})" + "\":/class_{lcls}") + ntype = arg.attrib["type"] + nname = arg.attrib["name"] + + if "default" in arg.attrib: + args.insert( + -1, + twd.format( + type=tlk.format( + cls=ntype, + lcls=ntype.lower()), + name=nname, + default=arg.attrib["default"])) + else: + # No default value present + args.insert( + -1, + tnd.format( + type=tlk.format( + cls=ntype, + lcls=ntype.lower()), + name=nname)) + # join the arguments together + finalstr += ", ".join(args) + # and, close the function with a ) + finalstr += " )" + # write the qualifier, if any + if "qualifiers" in node.attrib: + qualifier = node.attrib["qualifiers"] + finalstr += " " + qualifier + + finalstr += "\n" + + return finalstr + desc = "Generates documentation from a XML file to different markup languages" parser = argparse.ArgumentParser(description=desc) @@ -100,18 +238,20 @@ if "version" not in root.attrib: version = root.attrib["version"] classes = sorted(root, key=sortkey) +logging.debug("Number of classes: {}".format(len(classes))) +logging.debug("len(classes) / 2 + 1: {}".format(int(len(classes) / 2 + 1))) # first column is always longer, second column of classes should be shorter -zclasses = izip_longest(classes[:len(classes) / 2 + 1], - classes[len(classes) / 2 + 1:], - fillvalue="") +zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)], + classes[int(len(classes) / 2 + 1):], + fillvalue="") # We write the class_list file and also each class file at once with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: # Write header of table - fcl.write("|^.\n") - fcl.write("|_. Index symbol |_. Class name " - "|_. Index symbol |_. Class name |\n") - fcl.write("|-.\n") + fcl.write(tb("|^.\n")) + fcl.write(tb("|_. Index symbol |_. Class name " + "|_. Index symbol |_. Class name |\n")) + fcl.write(tb("|-.\n")) indexletterl = "" indexletterr = "" @@ -120,65 +260,119 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: # write the index symbol column, left if indexletterl != gdclassl.attrib["name"][0]: indexletterl = gdclassl.attrib["name"][0] - fcl.write("| *{}* |".format(indexletterl.upper())) + fcl.write(tb("| *{}* |".format(indexletterl.upper()))) else: # empty cell - fcl.write("| |") + fcl.write(tb("| |")) # write the class name column, left - fcl.write("\"{name}({title})\":/class_{link}".format( + fcl.write(tb("\"{name}({title})\":/class_{link}".format( name=gdclassl.attrib["name"], title="Go to page of class " + gdclassl.attrib["name"], - link="class_" + gdclassl.attrib["name"].lower())) + link="class_" + gdclassl.attrib["name"].lower()))) # write the index symbol column, right if isinstance(gdclassr, ElementTree.Element): if indexletterr != gdclassr.attrib["name"][0]: indexletterr = gdclassr.attrib["name"][0] - fcl.write("| *{}* |".format(indexletterr.upper())) + fcl.write(tb("| *{}* |".format(indexletterr.upper()))) else: # empty cell - fcl.write("| |") + fcl.write(tb("| |")) # We are dealing with an empty string else: # two empty cell - fcl.write("| | |\n") + fcl.write(tb("| | |\n")) # We won't get the name of the class since there is no ElementTree # object for the right side of the tuple, so we iterate the next # tuple instead continue # write the class name column (if any), right - fcl.write("\"{name}({title})\":/{link} |\n".format( + fcl.write(tb("\"{name}({title})\":/{link} |\n".format( name=gdclassr.attrib["name"], title="Go to page of class " + gdclassr.attrib["name"], - link=gdclassr.attrib["name"].lower())) + link=gdclassr.attrib["name"].lower()))) # row written # # now, let's write each class page for each class for gdclass in [gdclassl, gdclassr]: - if not isinstance(ElementTree.Element, gdclass): + if not isinstance(gdclass, ElementTree.Element): continue classname = gdclass.attrib["name"] with open(path.join(args.outputdir, "{}.txt".format( classname.lower())), "wb") as clsf: # First level header with the name of the class - clsf.write("h1. {}\n".format(classname)) + clsf.write(tb("h1. {}\n\n".format(classname))) # lay the attributes if "inherits" in gdclass.attrib: inh = gdclass.attrib["inherits"].strip() - clsf.write( - "*Inherits:* \"{name}({title})\":/class_{link}\n". - format( - name=classname, - title="Go to page of class " + classname, - link=classname.lower())) + clsf.write(tb(("h4. Inherits: \"{name}" + "({title})\":/class_{link}\n\n"). + format( + name=inh, + title="Go to page of class " + inh, + link=classname.lower()))) if "category" in gdclass.attrib: - clsf.write("*Category:* {}". - format(gdclass.attrib["category"].strip())) + clsf.write(tb("h4. Category: {}\n\n". + format(gdclass.attrib["category"].strip()))) # lay child nodes - for gdchild in gdclass.iter(): - if gdchild.tag == "brief_description": - clsf.write("h2. Brief Description\n") - clsf.write(toOP(gdchild.text.strip())) - # convert commands in text + briefd = gdclass.find("brief_description") + logging.debug( + "Brief description was found?: {}".format(briefd)) + if briefd.text.strip(): + logging.debug( + "Text: {}".format(briefd.text.strip())) + clsf.write(tb("h2. Brief Description\n\n")) + clsf.write(tb(toOP(briefd.text.strip()) + + "\"read more\":#more\n\n")) + + # Write the list of member functions of this class + methods = gdclass.find("methods") + if methods and len(methods) > 0: + clsf.write(tb("\nh3. Member Functions\n\n")) + for method in methods.iter(tag='method'): + clsf.write(tb(mkfn(method))) + + signals = gdclass.find("signals") + if signals and len(signals) > 0: + clsf.write(tb("\nh3. Signals\n\n")) + for signal in signals.iter(tag='signal'): + clsf.write(tb(mkfn(signal, True))) + # TODO: tag is necessary to process? it does not + # exists in class_list.xml file. + + consts = gdclass.find("constants") + if consts and len(consts) > 0: + clsf.write(tb("\nh3. Numeric Constants\n\n")) + for const in sorted(consts, key=lambda k: + k.attrib["name"]): + if const.text.strip(): + clsf.write(tb("* *{name}* = *{value}* - {desc}\n". + format( + name=const.attrib["name"], + value=const.attrib["value"], + desc=const.text.strip()))) + else: + # Constant have no description + clsf.write(tb("* *{name}* = *{value}*\n". + format( + name=const.attrib["name"], + value=const.attrib["value"]))) + descrip = gdclass.find("description") + clsf.write(tb("\nh3(#more). Description\n\n")) + if descrip.text: + clsf.write(tb(descrip.text.strip() + "\n")) + else: + clsf.write(tb("_Nothing here, yet..._\n")) + + # and finally, the description for each method + if methods and len(methods) > 0: + clsf.write(tb("\nh3. Member Function Description\n\n")) + for method in methods.iter(tag='method'): + clsf.write(tb("h4(#{n}). {name}\n\n".format( + n=method.attrib["name"].lower(), + name=method.attrib["name"]))) + clsf.write(tb(mkfn(method) + "\n")) + clsf.write(tb(toOP(method.find( + "description").text.strip()))) -- cgit v1.2.3 From f36d0fe4c56a7e82a814a682a136dfb07f922861 Mon Sep 17 00:00:00 2001 From: Jack Gold Date: Tue, 29 Sep 2015 22:38:23 -0400 Subject: Small readability fixes for the in-game class reference - fixes #2515 and #2393 (text spacing and top/left padding for the text area, respectively). --- tools/editor/editor_help.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/tools/editor/editor_help.cpp b/tools/editor/editor_help.cpp index 213c18e1b0..46ed2194a8 100644 --- a/tools/editor/editor_help.cpp +++ b/tools/editor/editor_help.cpp @@ -547,6 +547,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v class_desc->pop(); class_desc->add_newline(); class_desc->add_newline(); + class_desc->add_newline(); } @@ -563,6 +564,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v _add_text(cd.brief_description); class_desc->add_newline(); class_desc->add_newline(); + class_desc->add_newline(); } bool method_descr=false; @@ -637,7 +639,6 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v if (cd.properties.size()) { - class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color")); class_desc->push_font(doc_title_font); class_desc->add_text("Members:"); @@ -715,9 +716,10 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v class_desc->add_newline(); } - class_desc->add_newline(); class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); } if (cd.signals.size()) { @@ -779,6 +781,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v class_desc->pop(); class_desc->add_newline(); + class_desc->add_newline(); } @@ -823,6 +826,7 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v class_desc->pop(); class_desc->add_newline(); + class_desc->add_newline(); } @@ -830,17 +834,18 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v if (cd.description!="") { description_line=class_desc->get_line_count()-2; + class_desc->push_color(EditorSettings::get_singleton()->get("text_editor/keyword_color")); class_desc->push_font(doc_title_font); class_desc->add_text("Description:"); class_desc->pop(); class_desc->pop(); - class_desc->add_newline(); class_desc->add_newline(); _add_text(cd.description); class_desc->add_newline(); class_desc->add_newline(); + class_desc->add_newline(); } if (method_descr) { @@ -853,12 +858,16 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v class_desc->add_newline(); class_desc->add_newline(); + class_desc->push_indent(1); for(int i=0;iget_line_count()-2; + if( cd.methods[i].description != "") { + class_desc->add_newline(); + } class_desc->push_font(doc_code_font); _add_type(cd.methods[i].return_type); @@ -899,9 +908,12 @@ Error EditorHelp::_goto_desc(const String& p_class,bool p_update_history,int p_v class_desc->pop(); - class_desc->add_newline(); - class_desc->add_newline(); - _add_text(cd.methods[i].description); + if( cd.methods[i].description != "") { + class_desc->add_text(" "); + _add_text(cd.methods[i].description); + class_desc->add_newline(); + class_desc->add_newline(); + } class_desc->add_newline(); class_desc->add_newline(); @@ -1392,6 +1404,8 @@ EditorHelp::EditorHelp(EditorNode *p_editor) { PanelContainer *pc = memnew( PanelContainer ); Ref style( memnew( StyleBoxFlat ) ); style->set_bg_color( EditorSettings::get_singleton()->get("text_editor/background_color") ); + style->set_default_margin(MARGIN_LEFT,20); + style->set_default_margin(MARGIN_TOP,20); pc->add_style_override("panel", style); //get_stylebox("normal","TextEdit")); h_split->add_child(pc); class_desc = memnew( RichTextLabel ); -- cgit v1.2.3 From 1630f0ad3518422c3be76f6289f4b1d3e724907d Mon Sep 17 00:00:00 2001 From: volzhs Date: Wed, 30 Sep 2015 21:55:31 +0900 Subject: fix miss bind for Node::find_node --- scene/main/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 8336ce35f6..5c7e420c7b 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1931,7 +1931,7 @@ void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("has_node","path"),&Node::has_node); ObjectTypeDB::bind_method(_MD("get_node:Node","path"),&Node::get_node); ObjectTypeDB::bind_method(_MD("get_parent:Parent"),&Node::get_parent); - ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::get_node,DEFVAL(true),DEFVAL(true)); + ObjectTypeDB::bind_method(_MD("find_node:Node","mask","recursive","owned"),&Node::find_node,DEFVAL(true),DEFVAL(true)); ObjectTypeDB::bind_method(_MD("has_node_and_resource","path"),&Node::has_node_and_resource); ObjectTypeDB::bind_method(_MD("get_node_and_resource","path"),&Node::_get_node_and_resource); -- cgit v1.2.3 From a609a567ea033b99aaa7ad005313d39bec514172 Mon Sep 17 00:00:00 2001 From: Franklin Sobrinho Date: Sun, 4 Oct 2015 08:29:19 -0300 Subject: Fix bug in EditorPlugin::add_custom_control, fixes #2567 --- tools/editor/editor_plugin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/editor/editor_plugin.cpp b/tools/editor/editor_plugin.cpp index 04c34d9a88..7417d707bb 100644 --- a/tools/editor/editor_plugin.cpp +++ b/tools/editor/editor_plugin.cpp @@ -74,6 +74,7 @@ void EditorPlugin::add_custom_control(CustomControlContainer p_location,Control case CONTAINER_CANVAS_EDITOR_SIDE: { CanvasItemEditor::get_singleton()->get_palette_split()->add_child(p_control); + CanvasItemEditor::get_singleton()->get_palette_split()->move_child(p_control,0); } break; case CONTAINER_CANVAS_EDITOR_BOTTOM: { -- cgit v1.2.3 From 7f001a2c762d50d7502fefde477487b911ddee47 Mon Sep 17 00:00:00 2001 From: Zher Huei Lee Date: Mon, 5 Oct 2015 11:50:16 +0100 Subject: nested clipping of canvas items now works --- servers/visual/visual_server_raster.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index fbea60c3a6..cf840c1be3 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -6824,7 +6824,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*)); if (ci->clip) { - ci->final_clip_rect=global_rect; + if (p_canvas_clip != NULL) { + ci->final_clip_rect=p_canvas_clip->final_clip_rect.clip(global_rect); + } else { + ci->final_clip_rect=global_rect; + } ci->final_clip_owner=ci; } else { -- cgit v1.2.3 From 7c843fbc048a869eb4a03f774e9271d7f18c4d68 Mon Sep 17 00:00:00 2001 From: Jorge Araya Navarro Date: Tue, 6 Oct 2015 19:50:55 -0600 Subject: Refactoring some strings and ordering imports --- tools/docdump/makedocs.py | 122 ++++++++++++++++++++-------------------------- 1 file changed, 52 insertions(+), 70 deletions(-) diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py index 81469eed9c..303c94f79b 100644 --- a/tools/docdump/makedocs.py +++ b/tools/docdump/makedocs.py @@ -3,9 +3,7 @@ # # makedocs.py: Generate documentation for Open Project Wiki -# # Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. -# # Contributor: Jorge Araya Navarro # @@ -24,7 +22,7 @@ # whitespace you may left. # # TODO: -# * Refactor code. Refactor strings. +# * Refactor code. # * Adapt this script for generating content in other markup formats like # DokuWiki, Markdown, etc. # * Because people will translate class_list.xml, we should implement @@ -32,17 +30,33 @@ # # Also check other TODO entries in this script for more information on what is # left to do. - -import re import argparse import logging -from os import path +import re from itertools import zip_longest +from os import path from xml.etree import ElementTree + # add an option to change the verbosity logging.basicConfig(level=logging.INFO) +# Strings +C_LINK = ("\"{gclass}(Go to page of class" + " {gclass})\":/class_{lkclass}") +MC_LINK = ("\"{gclass}.{method}(Go " + "to page {gclass}, section {method})\"" + ":/class_{lkclass}#{lkmethod}") +TM_JUMP = ("\"{method}(Jump to method" + " {method})\":#{lkmethod}") +GTC_LINK = " \"{rtype}(Go to page of class {rtype})\":/class_{link} " +DFN_JUMP = ("\"*{funcname}*(Jump to description for" + " node {funcname})\":#{link} ( ") +M_ARG_DEFAULT = C_LINK + " {name}={default}" +M_ARG = C_LINK + " {name}" + +OPENPROJ_INH = ("h4. Inherits: " + C_LINK + "\n\n") + def tb(string): """ Return a byte representation of a string @@ -69,9 +83,7 @@ def sortkey(c): def toOP(text): """ Convert commands in text to Open Project commands """ - # We are going to do something very complicated with all HTML commands - # sadly, some commands are embedded inside other commands, so some steps - # are needed before converting some commands to Textile markup + # TODO: Make this capture content between [command] ... [/command] groups = re.finditer((r'\[html (?P/?\w+/?)(\]| |=)?(\]| |=)?(?P\w+)?(\]| |=)?(?P"[^"]+")?/?\]'), text) alignstr = "" @@ -106,27 +118,21 @@ def toOP(text): for group in groups: gd = group.groupdict() if gd["class"]: - replacewith = ("\"{gclass}.{method}(Go " - "to page {gclass}, section {method})\"" - ":/class_{lkclass}#{lkmethod}". - format(gclass=gd["class"], - method=gd["method"], - lkclass=gd["class"].lower(), - lkmethod=gd["method"].lower())) + replacewith = (MC_LINK.format(gclass=gd["class"], + method=gd["method"], + lkclass=gd["class"].lower(), + lkmethod=gd["method"].lower())) else: # The method is located in the same wiki page - replacewith = ("\"{method}(Jump to method" - " {method})\":#{lkmethod}". - format(method=gd["method"], - lkmethod=gd["method"].lower())) + replacewith = (TM_JUMP.format(method=gd["method"], + lkmethod=gd["method"].lower())) text = text.replace(group.group(0), replacewith, 1) # Finally, [Classes] are around brackets, make them direct links groups = re.finditer(r'\[(?P[az0-AZ0_]+)\]', text) for group in groups: gd = group.groupdict() - replacewith = ("\"{gclass}(Go to page of class" - " {gclass})\":/class_{lkclass}". + replacewith = (C_LINK. format(gclass=gd["class"], lkclass=gd["class"].lower())) text = text.replace(group.group(0), replacewith, 1) @@ -149,18 +155,16 @@ def mkfn(node, is_signal=False): # return type if not is_signal: if rtype != "void": - finalstr += " \"{rtype}({title})\":/class_{link} ".format( + finalstr += GTC_LINK.format( rtype=rtype, - title="Go to page of class " + rtype, link=rtype.lower()) else: finalstr += " void " # function name if not is_signal: - finalstr += "\"*{funcname}*({title})\":#{link} ( ".format( + finalstr += DFN_JUMP.format( funcname=name, - title="Jump to description for node " + name, link=name.lower()) else: # Signals have no description @@ -171,31 +175,19 @@ def mkfn(node, is_signal=False): node.iter(tag="argument"), key=lambda a: int(a.attrib["index"])): - twd = "{type} {name}={default}" - tnd = "{type} {name}" - tlk = ("\"*{cls}*(Go to page of class {cls})" - "\":/class_{lcls}") ntype = arg.attrib["type"] nname = arg.attrib["name"] if "default" in arg.attrib: - args.insert( - -1, - twd.format( - type=tlk.format( - cls=ntype, - lcls=ntype.lower()), - name=nname, - default=arg.attrib["default"])) + args.insert(-1, M_ARG_DEFAULT.format( + gclass=ntype, + lkclass=ntype.lower(), + name=nname, + default=arg.attrib["default"])) else: # No default value present - args.insert( - -1, - tnd.format( - type=tlk.format( - cls=ntype, - lcls=ntype.lower()), - name=nname)) + args.insert(-1, M_ARG.format(gclass=ntype, + lkclass=ntype.lower(), name=nname)) # join the arguments together finalstr += ", ".join(args) # and, close the function with a ) @@ -265,10 +257,9 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: # empty cell fcl.write(tb("| |")) # write the class name column, left - fcl.write(tb("\"{name}({title})\":/class_{link}".format( - name=gdclassl.attrib["name"], - title="Go to page of class " + gdclassl.attrib["name"], - link="class_" + gdclassl.attrib["name"].lower()))) + fcl.write(tb(C_LINK.format( + gclass=gdclassl.attrib["name"], + lkclass=gdclassl.attrib["name"].lower()))) # write the index symbol column, right if isinstance(gdclassr, ElementTree.Element): @@ -288,10 +279,9 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: continue # write the class name column (if any), right - fcl.write(tb("\"{name}({title})\":/{link} |\n".format( - name=gdclassr.attrib["name"], - title="Go to page of class " + gdclassr.attrib["name"], - link=gdclassr.attrib["name"].lower()))) + fcl.write(tb(C_LINK.format( + gclass=gdclassl.attrib["name"], + lkclass=gdclassl.attrib["name"].lower()) + "|\n")) # row written # # now, let's write each class page for each class @@ -307,36 +297,28 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: # lay the attributes if "inherits" in gdclass.attrib: inh = gdclass.attrib["inherits"].strip() - clsf.write(tb(("h4. Inherits: \"{name}" - "({title})\":/class_{link}\n\n"). - format( - name=inh, - title="Go to page of class " + inh, - link=classname.lower()))) + clsf.write(tb(OPENPROJ_INH.format(gclass=inh, + lkclass=inh.lower()))) if "category" in gdclass.attrib: clsf.write(tb("h4. Category: {}\n\n". format(gdclass.attrib["category"].strip()))) # lay child nodes briefd = gdclass.find("brief_description") - logging.debug( - "Brief description was found?: {}".format(briefd)) if briefd.text.strip(): - logging.debug( - "Text: {}".format(briefd.text.strip())) - clsf.write(tb("h2. Brief Description\n\n")) + clsf.write(b"h2. Brief Description\n\n") clsf.write(tb(toOP(briefd.text.strip()) + "\"read more\":#more\n\n")) # Write the list of member functions of this class methods = gdclass.find("methods") if methods and len(methods) > 0: - clsf.write(tb("\nh3. Member Functions\n\n")) + clsf.write(b"\nh3. Member Functions\n\n") for method in methods.iter(tag='method'): clsf.write(tb(mkfn(method))) signals = gdclass.find("signals") if signals and len(signals) > 0: - clsf.write(tb("\nh3. Signals\n\n")) + clsf.write(b"\nh3. Signals\n\n") for signal in signals.iter(tag='signal'): clsf.write(tb(mkfn(signal, True))) # TODO: tag is necessary to process? it does not @@ -344,7 +326,7 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: consts = gdclass.find("constants") if consts and len(consts) > 0: - clsf.write(tb("\nh3. Numeric Constants\n\n")) + clsf.write(b"\nh3. Numeric Constants\n\n") for const in sorted(consts, key=lambda k: k.attrib["name"]): if const.text.strip(): @@ -360,15 +342,15 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: name=const.attrib["name"], value=const.attrib["value"]))) descrip = gdclass.find("description") - clsf.write(tb("\nh3(#more). Description\n\n")) + clsf.write(b"\nh3(#more). Description\n\n") if descrip.text: clsf.write(tb(descrip.text.strip() + "\n")) else: - clsf.write(tb("_Nothing here, yet..._\n")) + clsf.write(b"_Nothing here, yet..._\n") # and finally, the description for each method if methods and len(methods) > 0: - clsf.write(tb("\nh3. Member Function Description\n\n")) + clsf.write(b"\nh3. Member Function Description\n\n") for method in methods.iter(tag='method'): clsf.write(tb("h4(#{n}). {name}\n\n".format( n=method.attrib["name"].lower(), -- cgit v1.2.3 From 68d005760bcfc498aad61719630b7ae21b4f31d8 Mon Sep 17 00:00:00 2001 From: Jorge Araya Navarro Date: Wed, 7 Oct 2015 13:11:17 -0600 Subject: Internationalization implemented Specify which language you want the templates translate to with the `--language` option and any choice language available. By default English is used. When class_list.xml is translated to different language than English this option will be useful to make the template language match. --- tools/docdump/locales/es/LC_MESSAGES/makedocs.mo | Bin 0 -> 2321 bytes tools/docdump/locales/es/LC_MESSAGES/makedocs.po | 142 +++++++++++++++++++++++ tools/docdump/makedocs.pot | 108 +++++++++++++++++ tools/docdump/makedocs.py | 128 +++++++++++--------- 4 files changed, 326 insertions(+), 52 deletions(-) create mode 100644 tools/docdump/locales/es/LC_MESSAGES/makedocs.mo create mode 100644 tools/docdump/locales/es/LC_MESSAGES/makedocs.po create mode 100644 tools/docdump/makedocs.pot diff --git a/tools/docdump/locales/es/LC_MESSAGES/makedocs.mo b/tools/docdump/locales/es/LC_MESSAGES/makedocs.mo new file mode 100644 index 0000000000..8d7ea2689e Binary files /dev/null and b/tools/docdump/locales/es/LC_MESSAGES/makedocs.mo differ diff --git a/tools/docdump/locales/es/LC_MESSAGES/makedocs.po b/tools/docdump/locales/es/LC_MESSAGES/makedocs.po new file mode 100644 index 0000000000..82115dd897 --- /dev/null +++ b/tools/docdump/locales/es/LC_MESSAGES/makedocs.po @@ -0,0 +1,142 @@ +# Translations template for PROJECT. +# Copyright (C) 2015 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2015. +# +msgid "" +msgstr "" +"Project-Id-Version: makedocs\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2015-10-07 11:47-0600\n" +"PO-Revision-Date: 2015-10-07 13:10-0600\n" +"Last-Translator: Jorge Araya Navarro \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.0\n" +"X-Generator: Poedit 1.8.4\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: makedocs.py:74 +msgid "" +"\"{gclass}(Go to page of class {gclass})\":/class_{lkclass}" +msgstr "" +"\"{gclass}(Ir a la pagina de la clase {gclass})\":/" +"class_{lkclass}" + +#: makedocs.py:76 +msgid "" +"\"{gclass}.{method}(Go to page {gclass}, section {method})\":/" +"class_{lkclass}#{lkmethod}" +msgstr "" +"\"{gclass}.{method}(Ir a la pagina {gclass}, secciĂłn " +"{method})\":/class_{lkclass}#{lkmethod}" + +#: makedocs.py:79 +msgid "\"{method}(Jump to method {method})\":#{lkmethod}" +msgstr "\"{method}(Saltar al mĂ©todo {method})\":#{lkmethod}" + +#: makedocs.py:81 +msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} " +msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} " + +#: makedocs.py:82 +msgid "" +"\"*{funcname}*(Jump to description for node {funcname})\":#{link} ( " +msgstr "" +"\"*{funcname}*(Saltar a la descripciĂłn para el nodo {funcname})\":#{link} " +"( " + +#: makedocs.py:87 +msgid "h4. Inherits: " +msgstr "h4. Hereda de: " + +#: makedocs.py:232 +msgid "'s version attribute missing" +msgstr "El atributo version de no existe" + +#: makedocs.py:246 +msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n" +msgstr "" +"|_. ĂŤndice de sĂ­mbolo |_. Nombre de la clase |_. ĂŤndice de sĂ­mbolo |_. " +"Nombre de la clase |\n" + +#: makedocs.py:305 +msgid "" +"h4. Category: {}\n" +"\n" +msgstr "" +"h4. CategorĂ­a: {}\n" +"\n" + +#: makedocs.py:310 +msgid "" +"h2. Brief Description\n" +"\n" +msgstr "" +"h2. DescripciĂłn breve\n" +"\n" + +#: makedocs.py:312 +msgid "" +"\"read more\":#more\n" +"\n" +msgstr "" +"\"Leer más\":#more\n" +"\n" + +#: makedocs.py:317 +msgid "" +"\n" +"h3. Member Functions\n" +"\n" +msgstr "" +"\n" +"h3. Funciones miembro\n" +"\n" + +#: makedocs.py:323 +msgid "" +"\n" +"h3. Signals\n" +"\n" +msgstr "" +"\n" +"h3. Señales\n" +"\n" + +#: makedocs.py:331 +msgid "" +"\n" +"h3. Numeric Constants\n" +"\n" +msgstr "" +"\n" +"h3. Constantes numĂ©ricas\n" +"\n" + +#: makedocs.py:347 +msgid "" +"\n" +"h3(#more). Description\n" +"\n" +msgstr "" +"\n" +"h3(#more). DescripciĂłn\n" +"\n" + +#: makedocs.py:351 +msgid "_Nothing here, yet..._\n" +msgstr "_AĂşn nada por aquĂ­..._\n" + +#: makedocs.py:355 +msgid "" +"\n" +"h3. Member Function Description\n" +"\n" +msgstr "" +"\n" +"h3. DescripciĂłn de las funciones miembro\n" +"\n" diff --git a/tools/docdump/makedocs.pot b/tools/docdump/makedocs.pot new file mode 100644 index 0000000000..be3220f686 --- /dev/null +++ b/tools/docdump/makedocs.pot @@ -0,0 +1,108 @@ +# Translations template for PROJECT. +# Copyright (C) 2015 ORGANIZATION +# This file is distributed under the same license as the PROJECT project. +# FIRST AUTHOR , 2015. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: makedocs 0.1\n" +"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" +"POT-Creation-Date: 2015-10-07 11:47-0600\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Babel 2.0\n" +"X-Generator: Poedit 1.8.4\n" + +#: makedocs.py:74 +msgid "\"{gclass}(Go to page of class {gclass})\":/class_{lkclass}" +msgstr "" + +#: makedocs.py:76 +msgid "\"{gclass}.{method}(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}" +msgstr "" + +#: makedocs.py:79 +msgid "\"{method}(Jump to method {method})\":#{lkmethod}" +msgstr "" + +#: makedocs.py:81 +msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} " +msgstr "" + +#: makedocs.py:82 +msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} ( " +msgstr "" + +#: makedocs.py:87 +msgid "h4. Inherits: " +msgstr "" + +#: makedocs.py:232 +msgid "'s version attribute missing" +msgstr "" + +#: makedocs.py:246 +msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n" +msgstr "" + +#: makedocs.py:305 +msgid "" +"h4. Category: {}\n" +"\n" +msgstr "" + +#: makedocs.py:310 +msgid "" +"h2. Brief Description\n" +"\n" +msgstr "" + +#: makedocs.py:312 +msgid "" +"\"read more\":#more\n" +"\n" +msgstr "" + +#: makedocs.py:317 +msgid "" +"\n" +"h3. Member Functions\n" +"\n" +msgstr "" + +#: makedocs.py:323 +msgid "" +"\n" +"h3. Signals\n" +"\n" +msgstr "" + +#: makedocs.py:331 +msgid "" +"\n" +"h3. Numeric Constants\n" +"\n" +msgstr "" + +#: makedocs.py:347 +msgid "" +"\n" +"h3(#more). Description\n" +"\n" +msgstr "" + +#: makedocs.py:351 +msgid "_Nothing here, yet..._\n" +msgstr "" + +#: makedocs.py:355 +msgid "" +"\n" +"h3. Member Function Description\n" +"\n" +msgstr "" diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py index 303c94f79b..280ce03532 100644 --- a/tools/docdump/makedocs.py +++ b/tools/docdump/makedocs.py @@ -25,37 +25,88 @@ # * Refactor code. # * Adapt this script for generating content in other markup formats like # DokuWiki, Markdown, etc. -# * Because people will translate class_list.xml, we should implement -# internalization. # # Also check other TODO entries in this script for more information on what is # left to do. +import gettext import argparse import logging import re from itertools import zip_longest from os import path +from os import listdir from xml.etree import ElementTree # add an option to change the verbosity logging.basicConfig(level=logging.INFO) + +def getxmlfloc(): + """ Returns the supposed location of the XML file + """ + filepath = path.dirname(path.abspath(__file__)) + return path.join(filepath, "class_list.xml") + + +def langavailable(): + """ Return a list of languages available for translation + """ + filepath = path.join( + path.dirname(path.abspath(__file__)), "locales") + files = listdir(filepath) + choices = [x for x in files] + choices.insert(0, "none") + return choices + + +desc = "Generates documentation from a XML file to different markup languages" + +parser = argparse.ArgumentParser(description=desc) +parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(), + help="Input XML file, default: {}".format(getxmlfloc())) +parser.add_argument("--output-dir", dest="outputdir", required=True, + help="Output directory for generated files") +parser.add_argument("--language", choices=langavailable(), default="none", + help=("Choose the language of translation" + " for the output files. Default is English (none). " + "Note: This is NOT for the documentation itself!")) +# TODO: add an option for outputting different markup formats + +args = parser.parse_args() +# Let's check if the file and output directory exists +if not path.isfile(args.xmlfp): + logging.critical("File not found: {}".format(args.xmlfp)) + exit(1) +elif not path.isdir(args.outputdir): + logging.critical("Path does not exist: {}".format(args.outputdir)) + exit(1) + +_ = gettext.gettext +if args.language != "none": + logging.info("Language changed to: " + args.language) + lang = gettext.translation(domain="makedocs", + localedir="locales", + languages=[args.language]) + lang.install() + + _ = lang.gettext + # Strings -C_LINK = ("\"{gclass}(Go to page of class" - " {gclass})\":/class_{lkclass}") -MC_LINK = ("\"{gclass}.{method}(Go " - "to page {gclass}, section {method})\"" - ":/class_{lkclass}#{lkmethod}") -TM_JUMP = ("\"{method}(Jump to method" - " {method})\":#{lkmethod}") -GTC_LINK = " \"{rtype}(Go to page of class {rtype})\":/class_{link} " -DFN_JUMP = ("\"*{funcname}*(Jump to description for" - " node {funcname})\":#{link} ( ") +C_LINK = _("\"{gclass}(Go to page of class" + " {gclass})\":/class_{lkclass}") +MC_LINK = _("\"{gclass}.{method}(Go " + "to page {gclass}, section {method})\"" + ":/class_{lkclass}#{lkmethod}") +TM_JUMP = _("\"{method}(Jump to method" + " {method})\":#{lkmethod}") +GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ") +DFN_JUMP = _("\"*{funcname}*(Jump to description for" + " node {funcname})\":#{link} ( ") M_ARG_DEFAULT = C_LINK + " {name}={default}" M_ARG = C_LINK + " {name}" -OPENPROJ_INH = ("h4. Inherits: " + C_LINK + "\n\n") +OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n" def tb(string): @@ -64,13 +115,6 @@ def tb(string): return bytes(string, "UTF-8") -def getxmlfloc(): - """ Returns the supposed location of the XML file - """ - filepath = path.dirname(path.abspath(__file__)) - return path.join(filepath, "class_list.xml") - - def sortkey(c): """ Symbols are first, letters second """ @@ -201,37 +245,17 @@ def mkfn(node, is_signal=False): return finalstr -desc = "Generates documentation from a XML file to different markup languages" - -parser = argparse.ArgumentParser(description=desc) -parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(), - help="Input XML file, default: {}".format(getxmlfloc())) -parser.add_argument("--output-dir", dest="outputdir", required=True, - help="Output directory for generated files") -# TODO: add an option for outputting different markup formats - -args = parser.parse_args() -# Let's check if the file and output directory exists -if not path.isfile(args.xmlfp): - logging.critical("File not found: {}".format(args.xmlfp)) - exit(1) -elif not path.isdir(args.outputdir): - logging.critical("Path does not exist: {}".format(args.outputdir)) - exit(1) - # Let's begin tree = ElementTree.parse(args.xmlfp) root = tree.getroot() # Check version attribute exists in if "version" not in root.attrib: - logging.critical("'s version attribute missing") + logging.critical(_("'s version attribute missing")) exit(1) version = root.attrib["version"] classes = sorted(root, key=sortkey) -logging.debug("Number of classes: {}".format(len(classes))) -logging.debug("len(classes) / 2 + 1: {}".format(int(len(classes) / 2 + 1))) # first column is always longer, second column of classes should be shorter zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)], classes[int(len(classes) / 2 + 1):], @@ -241,8 +265,8 @@ zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)], with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: # Write header of table fcl.write(tb("|^.\n")) - fcl.write(tb("|_. Index symbol |_. Class name " - "|_. Index symbol |_. Class name |\n")) + fcl.write(tb(_("|_. Index symbol |_. Class name " + "|_. Index symbol |_. Class name |\n"))) fcl.write(tb("|-.\n")) indexletterl = "" @@ -300,25 +324,25 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: clsf.write(tb(OPENPROJ_INH.format(gclass=inh, lkclass=inh.lower()))) if "category" in gdclass.attrib: - clsf.write(tb("h4. Category: {}\n\n". + clsf.write(tb(_("h4. Category: {}\n\n"). format(gdclass.attrib["category"].strip()))) # lay child nodes briefd = gdclass.find("brief_description") if briefd.text.strip(): - clsf.write(b"h2. Brief Description\n\n") + clsf.write(tb(_("h2. Brief Description\n\n"))) clsf.write(tb(toOP(briefd.text.strip()) + - "\"read more\":#more\n\n")) + _("\"read more\":#more\n\n"))) # Write the list of member functions of this class methods = gdclass.find("methods") if methods and len(methods) > 0: - clsf.write(b"\nh3. Member Functions\n\n") + clsf.write(tb(_("\nh3. Member Functions\n\n"))) for method in methods.iter(tag='method'): clsf.write(tb(mkfn(method))) signals = gdclass.find("signals") if signals and len(signals) > 0: - clsf.write(b"\nh3. Signals\n\n") + clsf.write(tb(_("\nh3. Signals\n\n"))) for signal in signals.iter(tag='signal'): clsf.write(tb(mkfn(signal, True))) # TODO: tag is necessary to process? it does not @@ -326,7 +350,7 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: consts = gdclass.find("constants") if consts and len(consts) > 0: - clsf.write(b"\nh3. Numeric Constants\n\n") + clsf.write(tb(_("\nh3. Numeric Constants\n\n"))) for const in sorted(consts, key=lambda k: k.attrib["name"]): if const.text.strip(): @@ -342,15 +366,15 @@ with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl: name=const.attrib["name"], value=const.attrib["value"]))) descrip = gdclass.find("description") - clsf.write(b"\nh3(#more). Description\n\n") + clsf.write(tb(_("\nh3(#more). Description\n\n"))) if descrip.text: clsf.write(tb(descrip.text.strip() + "\n")) else: - clsf.write(b"_Nothing here, yet..._\n") + clsf.write(tb(_("_Nothing here, yet..._\n"))) # and finally, the description for each method if methods and len(methods) > 0: - clsf.write(b"\nh3. Member Function Description\n\n") + clsf.write(tb(_("\nh3. Member Function Description\n\n"))) for method in methods.iter(tag='method'): clsf.write(tb("h4(#{n}). {name}\n\n".format( n=method.attrib["name"].lower(), -- cgit v1.2.3 From 0fb91ef95b7887eae1a8a7741f3e20e66c2b4998 Mon Sep 17 00:00:00 2001 From: Jorge Araya Navarro Date: Wed, 7 Oct 2015 13:15:28 -0600 Subject: Minor changes --- tools/docdump/makedocs.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py index 280ce03532..921b049bd8 100644 --- a/tools/docdump/makedocs.py +++ b/tools/docdump/makedocs.py @@ -84,7 +84,6 @@ elif not path.isdir(args.outputdir): _ = gettext.gettext if args.language != "none": - logging.info("Language changed to: " + args.language) lang = gettext.translation(domain="makedocs", localedir="locales", languages=[args.language]) -- cgit v1.2.3 From 613962d48ad3dd131ef8847d5e65df1fbe2da054 Mon Sep 17 00:00:00 2001 From: Jorge Araya Navarro Date: Wed, 7 Oct 2015 13:24:52 -0600 Subject: Minor changes: Organizing imports --- tools/docdump/makedocs.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/docdump/makedocs.py b/tools/docdump/makedocs.py index 921b049bd8..be57891abc 100644 --- a/tools/docdump/makedocs.py +++ b/tools/docdump/makedocs.py @@ -28,13 +28,12 @@ # # Also check other TODO entries in this script for more information on what is # left to do. -import gettext import argparse +import gettext import logging import re from itertools import zip_longest -from os import path -from os import listdir +from os import path, listdir from xml.etree import ElementTree -- cgit v1.2.3 From bbca86577d5f8fafce1abc471088909f2630735f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=91=E8=97=A4=20=E7=9B=B4=E4=BA=BA?= Date: Fri, 9 Oct 2015 21:39:50 +0900 Subject: fix parentheses-equality warnings of osx clang --- core/io/unzip.c | 2 +- core/io/zip.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/core/io/unzip.c b/core/io/unzip.c index 0cd975211e..b438021ad7 100644 --- a/core/io/unzip.c +++ b/core/io/unzip.c @@ -1788,7 +1788,7 @@ extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) return UNZ_PARAMERROR; - if ((pfile_in_zip_read_info->read_buffer == NULL)) + if (pfile_in_zip_read_info->read_buffer==NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; diff --git a/core/io/zip.c b/core/io/zip.c index 8f6aeb922f..c4ab93ab81 100644 --- a/core/io/zip.c +++ b/core/io/zip.c @@ -1114,9 +1114,9 @@ extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, zi->ci.flag = flagBase; if ((level==8) || (level==9)) zi->ci.flag |= 2; - if ((level==2)) + if (level==2) zi->ci.flag |= 4; - if ((level==1)) + if (level==1) zi->ci.flag |= 6; if (password != NULL) zi->ci.flag |= 1; -- cgit v1.2.3 From 13ff4bde650149577185d6d4c61b924cf0896d98 Mon Sep 17 00:00:00 2001 From: eska Date: Fri, 9 Oct 2015 21:54:16 +0200 Subject: Fix Area2D type mask matching --- servers/physics_2d/space_2d_sw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index a71e6c4bf5..9f2f03baec 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -36,8 +36,8 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec if ((p_object->get_layer_mask()&p_layer_mask)==0) return false; - if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA && !(p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA)) - return false; + if (p_object->get_type()==CollisionObject2DSW::TYPE_AREA) + return p_type_mask&Physics2DDirectSpaceState::TYPE_MASK_AREA; Body2DSW *body = static_cast(p_object); -- cgit v1.2.3 From 375a7a727f215a1d790de9caf82cb2a5e89cf711 Mon Sep 17 00:00:00 2001 From: eska Date: Sat, 10 Oct 2015 02:33:26 +0200 Subject: Fix 3D Area mask matching --- servers/physics/space_sw.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index d36b004989..ba1c737530 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -34,10 +34,10 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) { - if ((p_object->get_layer_mask()&p_layer_mask)==0) - return false; + if (p_object->get_type()==CollisionObjectSW::TYPE_AREA) + return p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA; - if (p_object->get_type()==CollisionObjectSW::TYPE_AREA && !(p_type_mask&PhysicsDirectSpaceState::TYPE_MASK_AREA)) + if ((p_object->get_layer_mask()&p_layer_mask)==0) return false; BodySW *body = static_cast(p_object); -- cgit v1.2.3 From 793c53122ae155842beadf8742239d1c071cc1fd Mon Sep 17 00:00:00 2001 From: eska Date: Sat, 10 Oct 2015 05:46:47 +0200 Subject: Add type mask property to RayCast2D --- scene/2d/ray_cast_2d.cpp | 17 ++++++++++++++++- scene/2d/ray_cast_2d.h | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 05594fd79c..acc4c620e6 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -53,6 +53,16 @@ uint32_t RayCast2D::get_layer_mask() const { return layer_mask; } +void RayCast2D::set_type_mask(uint32_t p_mask) { + + type_mask=p_mask; +} + +uint32_t RayCast2D::get_type_mask() const { + + return type_mask; +} + bool RayCast2D::is_colliding() const{ return collided; @@ -162,7 +172,7 @@ void RayCast2D::_notification(int p_what) { Physics2DDirectSpaceState::RayResult rr; - if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) { + if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask,type_mask)) { collided=true; against=rr.collider_id; @@ -241,9 +251,13 @@ void RayCast2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask); + ObjectTypeDB::bind_method(_MD("set_type_mask","mask"),&RayCast2D::set_type_mask); + ObjectTypeDB::bind_method(_MD("get_type_mask"),&RayCast2D::get_type_mask); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled")); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to")); ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"type_mask",PROPERTY_HINT_FLAGS,"Static,Kinematic,Rigid,Character,Area"),_SCS("set_type_mask"),_SCS("get_type_mask")); } RayCast2D::RayCast2D() { @@ -253,5 +267,6 @@ RayCast2D::RayCast2D() { collided=false; against_shape=0; layer_mask=1; + type_mask=Physics2DDirectSpaceState::TYPE_MASK_COLLISION; cast_to=Vector2(0,50); } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index c7616be523..8c3ce8b3b3 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -44,6 +44,7 @@ class RayCast2D : public Node2D { Vector2 collision_normal; Set exclude; uint32_t layer_mask; + uint32_t type_mask; Vector2 cast_to; @@ -62,6 +63,9 @@ public: void set_layer_mask(uint32_t p_mask); uint32_t get_layer_mask() const; + void set_type_mask(uint32_t p_mask); + uint32_t get_type_mask() const; + bool is_colliding() const; Object *get_collider() const; int get_collider_shape() const; -- cgit v1.2.3 From 422929e87fbe91be1efedf1fe3a9a71d61e58b40 Mon Sep 17 00:00:00 2001 From: reduz Date: Sat, 10 Oct 2015 09:09:09 -0300 Subject: Large improvements on scene packing and management -Ability to edit and keep changes of instanced scenes and sub-scenes -Ability to inherit from other scenes --- core/path_db.cpp | 31 + core/path_db.h | 5 +- core/resource.h | 2 +- demos/2d/platformer/coin.gd | 8 + scene/main/node.cpp | 64 +- scene/main/node.h | 27 +- scene/register_scene_types.cpp | 11 +- scene/resources/packed_scene.cpp | 1105 +++++++++++++++++++++++++++++---- scene/resources/packed_scene.h | 98 ++- scene/resources/scene_format_text.cpp | 792 +++++++++++++++++++++++ scene/resources/scene_format_text.h | 46 ++ tools/editor/editor_node.cpp | 18 +- tools/editor/editor_node.h | 3 +- tools/editor/property_editor.cpp | 151 ++++- tools/editor/property_editor.h | 7 +- tools/editor/reparent_dialog.cpp | 1 + tools/editor/scene_tree_dock.cpp | 51 +- tools/editor/scene_tree_editor.cpp | 95 ++- tools/editor/scene_tree_editor.h | 7 +- 19 files changed, 2306 insertions(+), 216 deletions(-) create mode 100644 scene/resources/scene_format_text.cpp create mode 100644 scene/resources/scene_format_text.h diff --git a/core/path_db.cpp b/core/path_db.cpp index d3dc3aceb8..c6ea25d966 100644 --- a/core/path_db.cpp +++ b/core/path_db.cpp @@ -286,6 +286,37 @@ NodePath::NodePath(const Vector& p_path,const Vector& p_ data->property=p_property; } + +void NodePath::simplify() { + + if (!data) + return; + for(int i=0;ipath.size();i++) { + if (data->path.size()==1) + break; + if (data->path[i].operator String()==".") { + data->path.remove(i); + i--; + } else if (data->path[i].operator String()==".." && i>0 && data->path[i-1].operator String()!="." && data->path[i-1].operator String()!="..") { + //remove both + data->path.remove(i-1); + data->path.remove(i-1); + i-=2; + if (data->path.size()==0) { + data->path.push_back("."); + break; + } + } + } +} + +NodePath NodePath::simplified() const { + + NodePath np=*this; + np.simplify(); + return np; +} + NodePath::NodePath(const String& p_path) { data=NULL; diff --git a/core/path_db.h b/core/path_db.h index b4f13d50be..de84216006 100644 --- a/core/path_db.h +++ b/core/path_db.h @@ -84,7 +84,10 @@ public: bool operator==(const NodePath& p_path) const; bool operator!=(const NodePath& p_path) const; void operator=(const NodePath& p_path); - + + void simplify(); + NodePath simplified() const; + NodePath(const Vector& p_path,bool p_absolute,const String& p_property=""); NodePath(const Vector& p_path,const Vector& p_subpath,bool p_absolute,const String& p_property=""); NodePath(const NodePath& p_path); diff --git a/core/resource.h b/core/resource.h index 9d9c445e1d..3596abe673 100644 --- a/core/resource.h +++ b/core/resource.h @@ -130,7 +130,7 @@ public: void set_name(const String& p_name); String get_name() const; - void set_path(const String& p_path,bool p_take_over=false); + virtual void set_path(const String& p_path,bool p_take_over=false); String get_path() const; void set_subindex(int p_sub_index); diff --git a/demos/2d/platformer/coin.gd b/demos/2d/platformer/coin.gd index 3e31a395ae..983cd46d88 100644 --- a/demos/2d/platformer/coin.gd +++ b/demos/2d/platformer/coin.gd @@ -18,3 +18,11 @@ func _ready(): # Initalization here pass + + +func _on_coin_area_enter( area ): + pass # replace with function body + + +func _on_coin_area_enter_shape( area_id, area, area_shape, area_shape ): + pass # replace with function body diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 8336ce35f6..b02e9c5645 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -841,6 +841,20 @@ Node *Node::get_child(int p_index) const { return data.children[p_index]; } + +Node *Node::_get_child_by_name(const StringName& p_name) const { + + int cc=data.children.size(); + Node* const* cd=data.children.ptr(); + + for(int i=0;idata.name==p_name) + return cd[i]; + } + + return NULL; +} + Node *Node::_get_node(const NodePath& p_path) const { ERR_FAIL_COND_V( !data.inside_tree && p_path.is_absolute(), NULL ); @@ -906,8 +920,10 @@ Node *Node::_get_node(const NodePath& p_path) const { Node *Node::get_node(const NodePath& p_path) const { Node *node = _get_node(p_path); - ERR_EXPLAIN("Node not found: "+p_path); - ERR_FAIL_COND_V(!node,NULL); + if (!node) { + ERR_EXPLAIN("Node not found: "+p_path); + ERR_FAIL_COND_V(!node,NULL); + } return node; } @@ -1332,7 +1348,29 @@ String Node::get_filename() const { return data.filename; } +void Node::set_editable_instance(Node* p_node,bool p_editable) { + + ERR_FAIL_NULL(p_node); + ERR_FAIL_COND(!is_a_parent_of(p_node)); + NodePath p = get_path_to(p_node); + if (!p_editable) + data.editable_instances.erase(p); + else + data.editable_instances[p]=true; +} + +bool Node::is_editable_instance(Node *p_node) const { + + if (!p_node) + return false; //easier, null is never editable :) + ERR_FAIL_COND_V(!is_a_parent_of(p_node),false); + NodePath p = get_path_to(p_node); + return data.editable_instances.has(p); +} + + +#if 0 void Node::generate_instance_state() { @@ -1383,6 +1421,28 @@ Dictionary Node::get_instance_state() const { return data.instance_state; } +#endif + +void Node::set_scene_instance_state(const Ref& p_state) { + + data.instance_state=p_state; +} + +Ref Node::get_scene_instance_state() const{ + + return data.instance_state; +} + +void Node::set_scene_inherited_state(const Ref& p_state) { + + data.inherited_state=p_state; +} + +Ref Node::get_scene_inherited_state() const{ + + return data.inherited_state; +} + Vector Node::get_instance_groups() const { return data.instance_groups; diff --git a/scene/main/node.h b/scene/main/node.h index a6d5bfbd9f..55557c6356 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -38,6 +38,7 @@ class Viewport; +class SceneState; class Node : public Object { OBJ_TYPE( Node, Object ); @@ -69,7 +70,11 @@ private: struct Data { String filename; - Dictionary instance_state; + Ref instance_state; + Ref inherited_state; + + HashMap editable_instances; + Vector instance_groups; Vector instance_connections; @@ -96,6 +101,7 @@ private: PauseMode pause_mode; Node *pause_owner; // variables used to properly sort the node when processing, ignored otherwise + //should move all the stuff below to bits bool fixed_process; bool idle_process; @@ -105,6 +111,7 @@ private: bool parent_owned; bool in_constructor; + } data; @@ -112,6 +119,7 @@ private: virtual bool _use_builtin_script() const { return true; } Node *_get_node(const NodePath& p_path) const; + Node *_get_child_by_name(const StringName& p_name) const; @@ -151,7 +159,7 @@ protected: static void _bind_methods(); -friend class PackedScene; +friend class SceneState; void _add_child_nocheck(Node* p_child,const StringName& p_name); void _set_owner_nocheck(Node* p_owner); @@ -208,7 +216,7 @@ public: struct GroupInfo { - String name; + StringName name; bool persistent; }; @@ -229,7 +237,10 @@ public: void set_filename(const String& p_filename); String get_filename() const; - + + void set_editable_instance(Node* p_node,bool p_editable); + bool is_editable_instance(Node* p_node) const; + /* NOTIFICATIONS */ void propagate_notification(int p_notification); @@ -261,8 +272,12 @@ public: //Node *clone_tree() const; // used by editors, to save what has changed only - void generate_instance_state(); - Dictionary get_instance_state() const; + void set_scene_instance_state(const Ref& p_state); + Ref get_scene_instance_state() const; + + void set_scene_inherited_state(const Ref& p_state); + Ref get_scene_inherited_state() const; + Vector get_instance_groups() const; Vector get_instance_connections() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 851de4a89f..ede586dc8d 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -216,7 +216,7 @@ #include "scene/3d/collision_polygon.h" #endif - +#include "scene/resources/scene_format_text.h" static ResourceFormatLoaderImage *resource_loader_image=NULL; static ResourceFormatLoaderWAV *resource_loader_wav=NULL; @@ -229,6 +229,8 @@ static ResourceFormatLoaderBitMap *resource_loader_bitmap=NULL; static ResourceFormatLoaderTheme *resource_loader_theme=NULL; static ResourceFormatLoaderShader *resource_loader_shader=NULL; +static ResourceFormatSaverText *resource_saver_text=NULL; + //static SceneStringNames *string_names; void register_scene_types() { @@ -612,6 +614,9 @@ void register_scene_types() { OS::get_singleton()->yield(); //may take time to init + resource_saver_text = memnew( ResourceFormatSaverText ); + ResourceSaver::add_resource_format_saver(resource_saver_text); + } void unregister_scene_types() { @@ -629,5 +634,9 @@ void unregister_scene_types() { memdelete( resource_loader_theme ); memdelete( resource_loader_shader ); + + if (resource_saver_text) { + memdelete(resource_saver_text); + } SceneStringNames::free(); } diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index b6082c3a76..86e7fe7f76 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -33,12 +33,28 @@ #include "scene/gui/control.h" #include "scene/2d/node_2d.h" -bool PackedScene::can_instance() const { +#define PACK_VERSION 2 + +bool SceneState::can_instance() const { return nodes.size()>0; } -Node *PackedScene::instance(bool p_gen_edit_state) const { + +Node *SceneState::instance(bool p_gen_edit_state) const { + + // nodes where instancing failed (because something is missing) + List stray_instances; + +#define NODE_FROM_ID(p_name,p_id)\ + Node *p_name;\ + if (p_id&FLAG_ID_IS_PATH) {\ + NodePath np=node_paths[p_id&FLAG_MASK];\ + p_name=ret_nodes[0]->_get_node(np);\ + } else {\ + ERR_FAIL_INDEX_V(p_id&FLAG_MASK,nc,NULL);\ + p_name=ret_nodes[p_id&FLAG_MASK];\ + } int nc = nodes.size(); ERR_FAIL_COND_V(nc==0,NULL); @@ -59,29 +75,58 @@ Node *PackedScene::instance(bool p_gen_edit_state) const { Node **ret_nodes=(Node**)alloca( sizeof(Node*)*nc ); + bool gen_node_path_cache=p_gen_edit_state && node_path_cache.empty(); for(int i=0;i0) { + + NODE_FROM_ID(nparent,n.parent); +#ifdef DEBUG_ENABLED + if (!nparent && n.parent&FLAG_ID_IS_PATH) { + + WARN_PRINT(String("Parent path '"+String(node_paths[n.parent&FLAG_MASK])+"' for node '"+String(snames[n.name])+"' has vanished when instancing: '"+get_path()+"'.").ascii().get_data()); + + } +#endif + parent=nparent; } Node *node=NULL; - if (n.instance>=0) { - //instance existing + if (i==0 && base_scene_idx>=0) { + //scene inheritance on root node + Ref sdata = props[ base_scene_idx ]; + ERR_FAIL_COND_V( !sdata.is_valid(), NULL); + node = sdata->instance(p_gen_edit_state); + ERR_FAIL_COND_V(!node,NULL); + if (p_gen_edit_state) { + node->set_scene_inherited_state(sdata->get_state()); + } + + } else if (n.instance>=0) { + //instance a scene into this node Ref sdata = props[ n.instance ]; ERR_FAIL_COND_V( !sdata.is_valid(), NULL); - node = sdata->instance(); + node = sdata->instance(p_gen_edit_state); ERR_FAIL_COND_V(!node,NULL); - if (p_gen_edit_state) - node->generate_instance_state(); - } else { - //create anew + } else if (n.type==TYPE_INSTANCED) { + //get the node from somewhere, it likely already exists from another instance + if (parent) { + node=parent->_get_child_by_name(snames[n.name]); +#ifdef DEBUG_ENABLED + if (!node) { + WARN_PRINT(String("Node '"+String(ret_nodes[0]->get_path_to(parent))+"/"+String(snames[n.name])+"' was modified from inside a instance, but it has vanished.").ascii().get_data()); + } +#endif + } + } else if (ObjectTypeDB::is_type_enabled(snames[n.type])) { + //node belongs to this scene and must be created Object * obj = ObjectTypeDB::instance(snames[ n.type ]); if (!obj || !obj->cast_to()) { if (obj) { @@ -109,49 +154,68 @@ Node *PackedScene::instance(bool p_gen_edit_state) const { } - //properties - int nprop_count=n.properties.size(); - if (nprop_count) { + if (node) { + // may not have found the node (part of instanced scene and removed) + // if found all is good, otherwise ignore + + //properties + int nprop_count=n.properties.size(); + if (nprop_count) { - const NodeData::Property* nprops=&n.properties[0]; + const NodeData::Property* nprops=&n.properties[0]; - for(int j=0;jset(snames[ nprops[j].name ],props[ nprops[j].value ],&valid); + node->set(snames[ nprops[j].name ],props[ nprops[j].value ],&valid); + } } - } - //name + //name - //groups - for(int j=0;jadd_to_group( snames[ n.groups[j] ], true ); - } + ERR_FAIL_INDEX_V( n.groups[j], sname_count, NULL ); + node->add_to_group( snames[ n.groups[j] ], true ); + } + if (n.instance>=0 || n.type!=TYPE_INSTANCED) { + //if node was not part of instance, must set it's name, parenthood and ownership + if (i>0) { + if (parent) { + parent->_add_child_nocheck(node,snames[n.name]); + } else { + //it may be possible that an instanced scene has changed + //and the node has nowhere to go anymore + stray_instances.push_back(node); //can't be added, go to stray list + } + } else { + node->_set_name_nocheck( snames[ n.name ] ); + } - ret_nodes[i]=node; + } - if (i>0) { - ERR_FAIL_INDEX_V(n.parent,i,NULL); - ERR_FAIL_COND_V(!ret_nodes[n.parent],NULL); - ret_nodes[n.parent]->_add_child_nocheck(node,snames[n.name]); - } else { - node->_set_name_nocheck( snames[ n.name ] ); - } + if (n.owner>=0) { + NODE_FROM_ID(owner,n.owner); + if (owner) + node->_set_owner_nocheck(owner); + } - if (n.owner>=0) { - ERR_FAIL_INDEX_V(n.owner,i,NULL); - node->_set_owner_nocheck(ret_nodes[n.owner]); } + + ret_nodes[i]=node; + + if (node && gen_node_path_cache && ret_nodes[0]) { + NodePath n = ret_nodes[0]->get_path_to(node); + node_path_cache[n]=i; + } } @@ -163,8 +227,14 @@ Node *PackedScene::instance(bool p_gen_edit_state) const { for(int i=0;i binds; if (c.binds.size()) { @@ -173,17 +243,25 @@ Node *PackedScene::instance(bool p_gen_edit_state) const { binds[j]=props[ c.binds[j] ]; } - if (!ret_nodes[c.from] || !ret_nodes[c.to]) - continue; - ret_nodes[c.from]->connect( snames[ c.signal], ret_nodes[ c.to ], snames[ c.method], binds,CONNECT_PERSIST|c.flags ); + + cfrom->connect( snames[ c.signal], cto, snames[ c.method], binds,CONNECT_PERSIST|c.flags ); } - Node *s = ret_nodes[0]; + //Node *s = ret_nodes[0]; - if (get_path()!="" && get_path().find("::")==-1) - s->set_filename(get_path()); + //remove nodes that could not be added, likely as a result that + while(stray_instances.size()) { + memdelete(stray_instances.front()->get()); + stray_instances.pop_front();; + } + + for(int i=0;i_get_node(editable_instances[i]); + if (ei) { + ret_nodes[0]->set_editable_instance(ei,true); + } + } - s->notification(Node::NOTIFICATION_INSTANCED); return ret_nodes[0]; } @@ -209,44 +287,150 @@ static int _vm_get_variant(const Variant& p_variant, HashMap &name_map,HashMap &variant_map,Map &node_map) { +Error SceneState::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map &name_map,HashMap &variant_map,Map &node_map,Map &nodepath_map) { + + + // this function handles all the work related to properly packing scenes, be it + // instanced or inherited. + // given the complexity of this process, an attempt will be made to properly + // document it. if you fail to understand something, please ask! - if (p_node!=p_owner && (p_node->get_owner()!=p_owner)) - return OK; //nothing to do with this node, may either belong to another scene or be onowned + //discard nodes that do not belong to be processed + if (p_node!=p_owner && p_node->get_owner()!=p_owner && !p_owner->is_editable_instance(p_node->get_owner())) + return OK; + + // save the child instanced scenes that are chosen as editable, so they can be restored + // upon load back + if (p_node!=p_owner && p_node->get_filename()!=String() && p_owner->is_editable_instance(p_node)) + editable_instances.push_back(p_owner->get_path_to(p_node)); NodeData nd; nd.name=_nm_get_string(p_node->get_name(),name_map); - nd.type=_nm_get_string(p_node->get_type(),name_map); - nd.parent=p_parent_idx; + nd.instance=-1; //not instanced by default + + // if this node is part of an instanced scene or sub-instanced scene + // we need to get the corresponding instance states. + // with the instance states, we can query for identical properties/groups + // and only save what has changed + + List pack_state_stack; + + bool instanced_by_owner=true; + { + Node *n=p_node; - Dictionary instance_state; - Set instance_groups; + while(n) { + if (n==p_owner) { + + Ref state = n->get_scene_inherited_state(); + if (state.is_valid()) { + int node = state->find_node_by_path(n->get_path_to(p_node)); + if (node>=0) { + //this one has state for this node, save + PackState ps; + ps.node=node; + ps.state=state; + pack_state_stack.push_front(ps); + instanced_by_owner=false; + } + } - if (p_node!=p_owner && p_node->get_filename()!="") { - //instanced + if (p_node->get_filename()!=String() && p_node->get_owner()==p_owner && instanced_by_owner) { + //must instance ourselves + Ref instance = ResourceLoader::load(p_node->get_filename()); + if (!instance.is_valid()) { + return ERR_CANT_OPEN; + } + + nd.instance=_vm_get_variant(instance,variant_map); + } + n=NULL; + } else { + if (n->get_filename()!=String()) { + //is an instance + Ref state = n->get_scene_instance_state(); + if (state.is_valid()) { + int node = state->find_node_by_path(n->get_path_to(p_node)); + if (node>=0) { + //this one has state for this node, save + PackState ps; + ps.node=node; + ps.state=state; + pack_state_stack.push_back(ps); + } + } + + } + n=n->get_owner(); + } + } + } + +#if 0 + + Ref base_scene = p_node->get_scene_inherited_state(); //for inheritance + Ref instance_state; + int instance_state_node=-1; + + if (base_scene.is_valid() && (p_node==p_owner || p_node->get_owner()==p_owner)) { + //scene inheritance in use, see if this node is actually inherited + NodePath path = p_owner->get_path_to(p_node); + instance_state_node = base_scene->find_node_by_path(path); + if (instance_state_node>=0) { + instance_state=base_scene; + } + } + + // check that this is a directly instanced scene from the scene being packed, if so + // this information must be saved. Of course, if using scene instancing and this node + // does belong to base scene, ignore. + + if (instance_state.is_null() && p_node!=p_owner && p_node->get_owner()==p_owner && p_node->get_filename()!="") { + + //instanced, only direct sub-scnes are supported of course Ref instance = ResourceLoader::load(p_node->get_filename()); if (!instance.is_valid()) { return ERR_CANT_OPEN; } nd.instance=_vm_get_variant(instance,variant_map); - instance_state = p_node->get_instance_state(); - Vector ig = p_node->get_instance_groups(); - for(int i=0;iget_owner()==p_owner && p_node->get_filename()!=String()) { + instance_state=p_node->get_scene_instance_state(); + if (instance_state.is_valid()) { + instance_state_node=instance_state->find_node_by_path(p_node->get_path_to(p_node)); + } + + } else if (p_node->get_owner()!=p_owner && p_owner->is_editable_instance(p_node->get_owner())) { + instance_state=p_node->get_owner()->get_scene_instance_state(); + if (instance_state.is_valid()) { + instance_state_node=instance_state->find_node_by_path(p_node->get_owner()->get_path_to(p_node)); + } + } + } +#endif + int subscene_prop_search_from=0; + + // all setup, we then proceed to check all properties for the node + // and save the ones that are worth saving List plist; p_node->get_property_list(&plist); + + for (List::Element *E=plist.front();E;E=E->next()) { @@ -257,34 +441,63 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map< String name = E->get().name; Variant value = p_node->get( E->get().name ); - if (nd.instance<0 && ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one())) { - continue; - } - print_line("PASSED!"); - print_line("at: "+String(p_node->get_name())+"::"+name+": - nz: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO)+" no: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONONE)); - print_line("value: "+String(value)+" is zero: "+itos(value.is_zero())+" is one" +itos(value.is_one())); + bool isdefault = ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one()); + +// if (nd.instance<0 && ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO) && value.is_zero()) || ((E->get().usage & PROPERTY_USAGE_STORE_IF_NONONE) && value.is_one())) { +// continue; +// } + - if (nd.instance>=0) { - //only save changed properties in instance - /* - // this was commented because it would not save properties created from within script - // done with _get_property_list, that are not in the original node. - // if some property is not saved, check again - if (!instance_state.has(name)) { - print_line("skip not in instance"); + //print_line("PASSED!"); + //print_line("at: "+String(p_node->get_name())+"::"+name+": - nz: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO)+" no: "+itos(E->get().usage&PROPERTY_USAGE_STORE_IF_NONONE)); + //print_line("value: "+String(value)+" is zero: "+itos(value.is_zero())+" is one" +itos(value.is_one())); + + if (pack_state_stack.size()) { + // we are on part of an instanced subscene + // or part of instanced scene. + // only save what has been changed + // only save changed properties in instance + + if (E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE || E->get().name=="__meta__") { + //property has requested that no instance state is saved, sorry + //also, meta won't be overriden or saved continue; - }*/ + } + + bool exists=false; + Variant original; + + for (List::Element *F=pack_state_stack.back();F;F=F->prev()) { + //check all levels of pack to see if the property exists somewhere + const PackState &ps=F->get(); + + original = ps.state->get_property_value(ps.node,E->get().name,exists); + if (exists) { + break; + } + } + - if (E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE) { + if (exists && bool(Variant::evaluate(Variant::OP_EQUAL,value,original))) { + //exists and did not change continue; } - if (instance_state.has(name) && instance_state[name]==value) { + if (!exists && isdefault) { + //does not exist in original node, but it's the default value + //so safe to skip too. continue; } + + } else { + + if (isdefault) { + //it's the default value, no point in saving it + continue; + } } NodeData::Property prop; @@ -295,6 +508,9 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map< } + // save the groups this node is into + // discard groups that come from the original scene + List groups; p_node->get_groups(&groups); for(List::Element *E=groups.front();E;E=E->next()) { @@ -302,27 +518,123 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map< if (!gi.persistent) continue; - if (nd.instance>=0 && instance_groups.has(gi.name)) - continue; //group was instanced, don't add here +// if (instance_state_node>=0 && instance_state->is_node_in_group(instance_state_node,gi.name)) +// continue; //group was instanced, don't add here + + bool skip=false; + for (List::Element *F=pack_state_stack.front();F;F=F->next()) { + //check all levels of pack to see if the group was added somewhere + const PackState &ps=F->get(); + if (ps.state->is_node_in_group(ps.node,gi.name)) { + skip=true; + break; + } + } + + if (skip) + continue; nd.groups.push_back(_nm_get_string(gi.name,name_map)); } - if (node_map.has(p_node->get_owner())) - nd.owner=node_map[p_node->get_owner()]; - else + + // save the right owner + // for the saved scene root this is -1 + // for nodes of the saved scene this is 0 + // for nodes of instanced scenes this is >0 + + if (p_node==p_owner) { + //saved scene root + nd.owner=-1; + } else if (p_node->get_owner()==p_owner) { + //part of saved scene + nd.owner=0; + } else { + nd.owner=-1; +#if 0 + // this is pointless, if this was instanced by something else, + // the owner will already be set. + + if (node_map.has(p_node->get_owner())) { + //maybe an existing saved node + nd.owner=node_map[p_node->get_owner()]; + } else { + //not saved, use nodepath map + int sidx; + if (nodepath_map.has(p_node->get_owner())) { + sidx=nodepath_map[p_node->get_owner()]; + } else { + sidx=nodepath_map.size(); + nodepath_map[p_node->get_owner()]=sidx; + } + + nd.owner=FLAG_ID_IS_PATH|sidx; + + } +#endif + + + } + + // Save the right type. If this node was created by an instance + // then flag that the node should not be created but reused + if (pack_state_stack.empty()) { + //this node is not part of an instancing process, so save the type + nd.type=_nm_get_string(p_node->get_type(),name_map); + } else { + // this node is part of an instanced process, so do not save the type. + // instead, save that it was instanced + nd.type=TYPE_INSTANCED; + } + + + // determine whether to save this node or not + // if this node is part of an instanced sub-scene, we can skip storing it if basically + // no properties changed and no groups were added to it. + // below condition is true for all nodes of the scene being saved, and ones in subscenes + // that hold changes + + bool save_node = nd.properties.size() || nd.groups.size(); // some local properties or groups exist + save_node = save_node || p_node==p_owner; // owner is always saved + save_node = save_node || (p_node->get_owner()==p_owner && instanced_by_owner); //part of scene and not instanced + int idx = nodes.size(); - node_map[p_node]=idx; - nodes.push_back(nd); + int parent_node=NO_PARENT_SAVED; + + if (save_node) { + + //don't save the node if nothing and subscene + + node_map[p_node]=idx; + + //ok validate parent node + if (p_parent_idx==NO_PARENT_SAVED) { + + int sidx; + if (nodepath_map.has(p_node->get_parent())) { + sidx=nodepath_map[p_node->get_parent()]; + } else { + sidx=nodepath_map.size(); + nodepath_map[p_node->get_parent()]=sidx; + } + + nd.parent=FLAG_ID_IS_PATH|sidx; + } else { + nd.parent=p_parent_idx; + } + + parent_node=idx; + nodes.push_back(nd); + } for(int i=0;iget_child_count();i++) { Node *c=p_node->get_child(i); - Error err = _parse_node(p_owner,c,idx,name_map,variant_map,node_map); + Error err = _parse_node(p_owner,c,parent_node,name_map,variant_map,node_map,nodepath_map); if (err) return err; } @@ -331,53 +643,135 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map< } -Error PackedScene::_parse_connections(Node *p_owner,Node *p_node, Map &name_map,HashMap &variant_map,Map &node_map) { - - if (p_node!=p_owner && (p_node->get_owner()!=p_owner)) - return OK; //nothing to do with this node, may either belong to another scene or be onowned - - List signals; - p_node->get_signal_list(&signals); +Error SceneState::_parse_connections(Node *p_owner,Node *p_node, Map &name_map,HashMap &variant_map,Map &node_map,Map &nodepath_map) { - ERR_FAIL_COND_V( !node_map.has(p_node), ERR_BUG); - NodeData &nd = nodes[node_map[p_node]]; - Set instance_connections; + if (p_node!=p_owner && p_node->get_owner() && p_node->get_owner()!=p_owner && !p_owner->is_editable_instance(p_node->get_owner())) + return OK; - if (nd.instance>=0) { - Vector iconns = p_node->get_instance_connections(); - for(int i=0;i _signals; + p_node->get_signal_list(&_signals); - instance_connections.insert(iconns[i]); - } - } + //ERR_FAIL_COND_V( !node_map.has(p_node), ERR_BUG); + //NodeData &nd = nodes[node_map[p_node]]; - for(List::Element *E=signals.front();E;E=E->next()) { + for(List::Element *E=_signals.front();E;E=E->next()) { List conns; p_node->get_signal_connection_list(E->get().name,&conns); for(List::Element *F=conns.front();F;F=F->next()) { const Node::Connection &c = F->get(); - if (!(c.flags&CONNECT_PERSIST)) + + if (!(c.flags&CONNECT_PERSIST)) //only persistent connections get saved continue; - if (nd.instance>=0 && instance_connections.has(c)) - continue; //came from instance, don't save! + // only connections that originate or end into main saved scene are saved + // everything else is discarded Node *n=c.target->cast_to(); - if (!n) + if (!n) { continue; + } + + //source node is outside saved scene? + bool src_is_out = p_node!=p_owner && (p_node->get_filename()!=String() || p_node->get_owner()!=p_owner); + //target node is outside saved scene? + bool dst_is_out = n!=p_owner && (n->get_filename()!=String() || n->get_owner()!=p_owner); - if (!node_map.has(n)) { - WARN_PRINT("Connection to node outside scene??") + //if both are out, ignore connection + if (src_is_out && dst_is_out) { continue; } + + { + Node *nl=p_node; + + bool exists=false; + + while(nl) { + + if (nl==p_owner) { + + Ref state = nl->get_scene_inherited_state(); + if (state.is_valid()) { + int from_node = state->find_node_by_path(nl->get_path_to(p_node)); + int to_node = state->find_node_by_path(nl->get_path_to(n)); + + if (from_node>=0 && to_node>=0) { + //this one has state for this node, save + if (state->is_connection(from_node,c.signal,to_node,c.method)) { + exists=true; + break; + } + } + } + + nl=NULL; + } else { + if (nl->get_filename()!=String()) { + //is an instance + Ref state = nl->get_scene_instance_state(); + if (state.is_valid()) { + int from_node = state->find_node_by_path(nl->get_path_to(p_node)); + int to_node = state->find_node_by_path(nl->get_path_to(n)); + + if (from_node>=0 && to_node>=0) { + //this one has state for this node, save + if (state->is_connection(from_node,c.signal,to_node,c.method)) { + exists=true; + break; + } + } + } + + } + nl=nl->get_owner(); + } + } + + if (exists) { + continue; + } + + } + + + int src_id; + + if (node_map.has(p_node)) { + src_id=node_map[p_node]; + } else { + if (nodepath_map.has(p_node)) { + src_id=FLAG_ID_IS_PATH|nodepath_map[p_node]; + } else { + int sidx=nodepath_map.size(); + nodepath_map[p_node]=sidx; + src_id=FLAG_ID_IS_PATH|sidx; + } + } + + + + int target_id; + + if (node_map.has(n)) { + target_id=node_map[n]; + } else { + if (nodepath_map.has(n)) { + target_id=FLAG_ID_IS_PATH|nodepath_map[n]; + } else { + int sidx=nodepath_map.size(); + nodepath_map[n]=sidx; + target_id=FLAG_ID_IS_PATH|sidx; + } + } + ConnectionData cd; - cd.from=node_map[p_node]; - cd.to=node_map[n]; + cd.from=src_id; + cd.to=target_id; cd.method=_nm_get_string(c.method,name_map); cd.signal=_nm_get_string(c.signal,name_map); cd.flags=c.flags; @@ -392,7 +786,7 @@ Error PackedScene::_parse_connections(Node *p_owner,Node *p_node, Mapget_child_count();i++) { Node *c=p_node->get_child(i); - Error err = _parse_connections(p_owner,c,name_map,variant_map,node_map); + Error err = _parse_connections(p_owner,c,name_map,variant_map,node_map,nodepath_map); if (err) return err; } @@ -401,7 +795,7 @@ Error PackedScene::_parse_connections(Node *p_owner,Node *p_node, Map name_map; HashMap variant_map; Map node_map; + Map nodepath_map; + + //if using scene inheritance, pack the scene it inherits from + if (scene->get_scene_inherited_state().is_valid()) { + String path = scene->get_scene_inherited_state()->get_path(); + Ref instance = ResourceLoader::load(path); + if (instance.is_valid()) { + + base_scene_idx=_vm_get_variant(instance,variant_map); + } + } + //instanced, only direct sub-scnes are supported of course + - Error err = _parse_node(scene,scene,-1,name_map,variant_map,node_map); + Error err = _parse_node(scene,scene,-1,name_map,variant_map,node_map,nodepath_map); if (err) { clear(); ERR_FAIL_V(err); } - err = _parse_connections(scene,scene,name_map,variant_map,node_map); + err = _parse_connections(scene,scene,name_map,variant_map,node_map,nodepath_map); if (err) { clear(); ERR_FAIL_V(err); @@ -440,19 +847,170 @@ Error PackedScene::pack(Node *p_scene) { variants[idx]=*K; } + node_paths.resize(nodepath_map.size()); + for(Map::Element *E=nodepath_map.front();E;E=E->next()) { + + node_paths[E->get()]=scene->get_path_to(E->key()); + } + + return OK; } -void PackedScene::clear() { +void SceneState::set_path(const String &p_path) { + + path=p_path; +} + +String SceneState::get_path() const{ + + return path; +} + +void SceneState::clear() { names.clear(); variants.clear(); nodes.clear(); connections.clear(); + node_path_cache.clear(); + node_paths.clear(); + editable_instances.clear(); + base_scene_idx=-1; } -void PackedScene::_set_bundled_scene(const Dictionary& d) { +Ref SceneState::_get_base_scene_state() const { + + if (base_scene_idx>=0) { + + Ref ps = variants[base_scene_idx]; + if (ps.is_valid()) { + return ps->get_state(); + } + } + + return Ref(); +} + +int SceneState::find_node_by_path(const NodePath& p_node) const { + + if (!node_path_cache.has(p_node)) { + if (_get_base_scene_state().is_valid()) { + int idx = _get_base_scene_state()->find_node_by_path(p_node); + if (idx>=0) { + if (!base_scene_node_remap.has(idx)) { + int ridx = nodes.size() + base_scene_node_remap.size(); + base_scene_node_remap[ridx]=idx; + } + + return base_scene_node_remap[idx]; + } + } + return -1; + } + + int nid = node_path_cache[p_node]; + + if (_get_base_scene_state().is_valid() && !base_scene_node_remap.has(nid)) { + //for nodes that _do_ exist in current scene, still try to look for + //the node in the instanced scene, as a property may be missing + //from the local one + int idx = _get_base_scene_state()->find_node_by_path(p_node); + base_scene_node_remap[nid]=idx; + + } + + return nid; +} +Variant SceneState::get_property_value(int p_node, const StringName& p_property, bool &found) const { + + found=false; + + ERR_FAIL_COND_V(p_node<0,Variant()); + + if (p_nodeget_property_value(base_scene_node_remap[p_node],p_property,found); + } + + return Variant(); +} + +bool SceneState::is_node_in_group(int p_node,const StringName& p_group) const { + + ERR_FAIL_COND_V(p_node<0,false); + + if (p_nodeis_node_in_group(base_scene_node_remap[p_node],p_group); + } + + return false; +} + +bool SceneState::is_connection(int p_node,const StringName& p_signal,int p_to_node,const StringName& p_to_method) const { + + ERR_FAIL_COND_V(p_node<0,false); + ERR_FAIL_COND_V(p_to_node<0,false); + + if (p_node=0 && method_idx>=0) { + //signal and method strings are stored.. + + for(int i=0;iis_connection(base_scene_node_remap[p_node],p_signal,base_scene_node_remap[p_to_node],p_to_method); + } + + return false; + +} + + +void SceneState::set_bundled_scene(const Dictionary& d) { ERR_FAIL_COND( !d.has("names")); @@ -463,6 +1021,15 @@ void PackedScene::_set_bundled_scene(const Dictionary& d) { ERR_FAIL_COND( !d.has("conns")); // ERR_FAIL_COND( !d.has("path")); + int version=1; + if (d.has("version")) + version=d["version"]; + + if (version>PACK_VERSION) { + ERR_EXPLAIN("Save format version too new!"); + ERR_FAIL(); + } + DVector snames = d["names"]; if (snames.size()) { @@ -540,11 +1107,34 @@ void PackedScene::_set_bundled_scene(const Dictionary& d) { } + Array np; + if (d.has("node_paths")) { + np=d["node_paths"]; + } + node_paths.resize(np.size()); + for(int i=0;i rnames; rnames.resize(names.size()); @@ -605,7 +1195,25 @@ Dictionary PackedScene::_get_bundled_scene() const { } d["conns"]=rconns; - d["version"]=1; + + Array rnode_paths; + rnode_paths.resize(node_paths.size()); + for(int i=0;i=0) { + d["base_scene"]=base_scene_idx; + } + + d["version"]=PACK_VERSION; // d["path"]=path; @@ -614,10 +1222,264 @@ Dictionary PackedScene::_get_bundled_scene() const { } +int SceneState::get_node_count() const { + + return nodes.size(); +} + +StringName SceneState::get_node_type(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,nodes.size(),StringName()); + if (nodes[p_idx].type==TYPE_INSTANCED) + return StringName(); + return names[nodes[p_idx].type]; +} + +StringName SceneState::get_node_name(int p_idx) const { + + ERR_FAIL_INDEX_V(p_idx,nodes.size(),StringName()); + return names[nodes[p_idx].name]; +} + +Ref SceneState::get_node_instance(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx,nodes.size(),Ref()); + if (nodes[p_idx].instance>=0) { + return variants[nodes[p_idx].instance]; + } else if (nodes[p_idx].parent<=0 || nodes[p_idx].parent==NO_PARENT_SAVED) { + + if (base_scene_idx>=0) { + return variants[base_scene_idx]; + } + } + + return Ref(); + + +} +Vector SceneState::get_node_groups(int p_idx) const{ + ERR_FAIL_INDEX_V(p_idx,nodes.size(),Vector()); + Vector groups; + for(int i=0;i sub_path; + NodePath base_path; + int nidx=p_idx; + while(true) { + if (nodes[nidx].parent==NO_PARENT_SAVED || nodes[nidx].parent<0) { + + sub_path.insert(0,"."); + break; + } + + if (!p_for_parent || p_idx!=nidx) { + sub_path.insert(0,names[nodes[nidx].name]); + } + + if (nodes[nidx].parent&FLAG_ID_IS_PATH) { + base_path=node_paths[nodes[nidx].parent&FLAG_MASK]; + break; + } else { + nidx=nodes[nidx].parent&FLAG_MASK; + } + } + + for(int i=0;i SceneState::get_editable_instances() const { + return editable_instances; +} + + +SceneState::SceneState() { + + base_scene_idx=-1; +} + + +//////////////// + + + +void PackedScene::_set_bundled_scene(const Dictionary& d) { + + state->set_bundled_scene(d); +} + +Dictionary PackedScene::_get_bundled_scene() const { + + return state->get_bundled_scene(); +} + + +Error PackedScene::pack(Node *p_scene) { + + return state->pack(p_scene); +} + +void PackedScene::clear() { + + state->clear(); +} + +bool PackedScene::can_instance() const { + + return state->can_instance(); +} + +Node *PackedScene::instance(bool p_gen_edit_state) const { + +#ifndef TOOLS_ENABLED + if (p_gen_edit_state) { + ERR_EXPLAIN("Edit state is only for editors, does not work without tools compiled"); + ERR_FAIL_COND_V(p_gen_edit_state,NULL); + } +#endif + + Node *s = state->instance(p_gen_edit_state); + if (!s) + return NULL; + + if (p_gen_edit_state) { + s->set_scene_instance_state(state); + } + + if (get_path()!="" && get_path().find("::")==-1) + s->set_filename(get_path()); + + + s->notification(Node::NOTIFICATION_INSTANCED); + + return s; +} + +Ref PackedScene::get_state() { + + return state; +} + +void PackedScene::set_path(const String& p_path,bool p_take_over) { + + state->set_path(p_path); + Resource::set_path(p_path,p_take_over); +} + void PackedScene::_bind_methods() { ObjectTypeDB::bind_method(_MD("pack","path:Node"),&PackedScene::pack); - ObjectTypeDB::bind_method(_MD("instance:Node"),&PackedScene::instance,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("instance:Node","gen_edit_state"),&PackedScene::instance,DEFVAL(false)); ObjectTypeDB::bind_method(_MD("can_instance"),&PackedScene::can_instance); ObjectTypeDB::bind_method(_MD("_set_bundled_scene"),&PackedScene::_set_bundled_scene); ObjectTypeDB::bind_method(_MD("_get_bundled_scene"),&PackedScene::_get_bundled_scene); @@ -628,5 +1490,6 @@ void PackedScene::_bind_methods() { PackedScene::PackedScene() { + state = Ref( memnew( SceneState )); } diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 6c7fa545d4..2a2271810e 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -32,18 +32,32 @@ #include "resource.h" #include "scene/main/node.h" -class PackedScene : public Resource { - OBJ_TYPE( PackedScene, Resource ); - RES_BASE_EXTENSION("scn"); +class SceneState : public Reference { + + OBJ_TYPE( SceneState, Reference ); Vector names; Vector variants; + Vector node_paths; + Vector editable_instances; + mutable HashMap node_path_cache; + mutable Map base_scene_node_remap; + + int base_scene_idx; //missing - instances //missing groups //missing - owner //missing - override names and values + enum { + FLAG_ID_IS_PATH=(1<<30), + FLAG_MASK=(1<<24)-1, + NO_PARENT_SAVED=0x7FFFFFFF, + TYPE_INSTANCED=0x7FFFFFFF, + + }; + struct NodeData { int parent; @@ -59,9 +73,15 @@ class PackedScene : public Resource { }; Vector properties; - Vector groups; + Vector groups; + }; + struct PackState { + Ref state; + int node; + PackState() { node=-1; } + }; Vector nodes; @@ -77,16 +97,75 @@ class PackedScene : public Resource { Vector connections; - Error _parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map &name_map,HashMap &variant_map,Map &node_map); - Error _parse_connections(Node *p_owner,Node *p_node, Map &name_map,HashMap &variant_map,Map &node_map); + Error _parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map &name_map,HashMap &variant_map,Map &node_map,Map &nodepath_map); + Error _parse_connections(Node *p_owner,Node *p_node, Map &name_map,HashMap &variant_map,Map &node_map,Map &nodepath_map); + + String path; + + _FORCE_INLINE_ Ref _get_base_scene_state() const; + +public: + + int find_node_by_path(const NodePath& p_node) const; + Variant get_property_value(int p_node,const StringName& p_property,bool &found) const; + bool is_node_in_group(int p_node,const StringName& p_group) const; + bool is_connection(int p_node,const StringName& p_signal,int p_to_node,const StringName& p_to_method) const; + + + void set_bundled_scene(const Dictionary& p_dictionary); + Dictionary get_bundled_scene() const; + + Error pack(Node *p_scene); + + void set_path(const String &p_path); + String get_path() const; + + void clear(); + + bool can_instance() const; + Node *instance(bool p_gen_edit_state=false) const; + + + //build-unbuild API + + int get_node_count() const; + StringName get_node_type(int p_idx) const; + StringName get_node_name(int p_idx) const; + NodePath get_node_path(int p_idx,bool p_for_parent=false) const; + NodePath get_node_owner_path(int p_idx) const; + Ref get_node_instance(int p_idx) const; + Vector get_node_groups(int p_idx) const; + + int get_node_property_count(int p_idx) const; + StringName get_node_property_name(int p_idx,int p_prop) const; + Variant get_node_property_value(int p_idx,int p_prop) const; + + int get_connection_count() const; + NodePath get_connection_source(int p_idx) const; + StringName get_connection_signal(int p_idx) const; + NodePath get_connection_target(int p_idx) const; + StringName get_connection_method(int p_idx) const; + int get_connection_flags(int p_idx) const; + Array get_connection_binds(int p_idx) const; + + Vector get_editable_instances() const; + + SceneState(); +}; + +class PackedScene : public Resource { + + OBJ_TYPE(PackedScene, Resource ); + RES_BASE_EXTENSION("scn"); + + Ref state; void _set_bundled_scene(const Dictionary& p_scene); Dictionary _get_bundled_scene() const; protected: - static void _bind_methods(); public: @@ -98,7 +177,12 @@ public: bool can_instance() const; Node *instance(bool p_gen_edit_state=false) const; + virtual void set_path(const String& p_path,bool p_take_over=false); + + Ref get_state(); + PackedScene(); + }; #endif // SCENE_PRELOADER_H diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp new file mode 100644 index 0000000000..8403c06ad1 --- /dev/null +++ b/scene/resources/scene_format_text.cpp @@ -0,0 +1,792 @@ +#include "scene_format_text.h" + +#include "globals.h" +#include "version.h" +#include "os/dir_access.h" + +#define FORMAT_VERSION 1 + +void ResourceFormatSaverTextInstance::write_property(const String& p_name,const Variant& p_property,bool *r_ok) { + + if (r_ok) + *r_ok=false; + + if (p_name!=String()) { + f->store_string(p_name+" = "); + } + + switch( p_property.get_type() ) { + + case Variant::NIL: { + f->store_string("null"); + } break; + case Variant::BOOL: { + + f->store_string(p_property.operator bool() ? "true":"false" ); + } break; + case Variant::INT: { + + f->store_string( itos(p_property.operator int()) ); + } break; + case Variant::REAL: { + + f->store_string( rtoss(p_property.operator real_t()) ); + } break; + case Variant::STRING: { + + String str=p_property; + + str="\""+str.c_escape()+"\""; + f->store_string( str ); + } break; + case Variant::VECTOR2: { + + Vector2 v = p_property; + f->store_string("Vector2( "+rtoss(v.x) +", "+rtoss(v.y)+" )" ); + } break; + case Variant::RECT2: { + + Rect2 aabb = p_property; + f->store_string("Rect2( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y)+" )" ); + + } break; + case Variant::VECTOR3: { + + Vector3 v = p_property; + f->store_string("Vector3( "+rtoss(v.x) +", "+rtoss(v.y)+", "+rtoss(v.z)+" )"); + } break; + case Variant::PLANE: { + + Plane p = p_property; + f->store_string("Plane( "+rtoss(p.normal.x) +", "+rtoss(p.normal.y)+", "+rtoss(p.normal.z)+", "+rtoss(p.d)+" )" ); + + } break; + case Variant::_AABB: { + + AABB aabb = p_property; + f->store_string("AABB( "+rtoss(aabb.pos.x) +", "+rtoss(aabb.pos.y) +", "+rtoss(aabb.pos.z) +", "+rtoss(aabb.size.x) +", "+rtoss(aabb.size.y) +", "+rtoss(aabb.size.z)+" )" ); + + } break; + case Variant::QUAT: { + + Quat quat = p_property; + f->store_string("Quat( "+rtoss(quat.x)+", "+rtoss(quat.y)+", "+rtoss(quat.z)+", "+rtoss(quat.w)+" )"); + + } break; + case Variant::MATRIX32: { + + String s="Matrix32( "; + Matrix32 m3 = p_property; + for (int i=0;i<3;i++) { + for (int j=0;j<2;j++) { + + if (i!=0 || j!=0) + s+=", "; + s+=rtoss( m3.elements[i][j] ); + } + } + + f->store_string(s+" )"); + + } break; + case Variant::MATRIX3: { + + String s="Matrix3( "; + Matrix3 m3 = p_property; + for (int i=0;i<3;i++) { + for (int j=0;j<3;j++) { + + if (i!=0 || j!=0) + s+=", "; + s+=rtoss( m3.elements[i][j] ); + } + } + + f->store_string(s+" )"); + + } break; + case Variant::TRANSFORM: { + + String s="Transform( "; + Transform t = p_property; + Matrix3 &m3 = t.basis; + for (int i=0;i<3;i++) { + for (int j=0;j<3;j++) { + + if (i!=0 || j!=0) + s+=", "; + s+=rtoss( m3.elements[i][j] ); + } + } + + s=s+", "+rtoss(t.origin.x) +", "+rtoss(t.origin.y)+", "+rtoss(t.origin.z); + + f->store_string(s+" )"); + } break; + + // misc types + case Variant::COLOR: { + + Color c = p_property; + f->store_string("Color( "+rtoss(c.r) +", "+rtoss(c.g)+", "+rtoss(c.b)+", "+rtoss(c.a)+" )"); + + } break; + case Variant::IMAGE: { + + + Image img=p_property; + + if (img.empty()) { + f->store_string("RawImage()"); + break; + } + + String imgstr="RawImage( "; + imgstr+=itos(img.get_width()); + imgstr+=", "+itos(img.get_height()); + imgstr+=", "+itos(img.get_mipmaps()); + imgstr+=", "; + + switch(img.get_format()) { + + case Image::FORMAT_GRAYSCALE: imgstr+="GRAYSCALE"; break; + case Image::FORMAT_INTENSITY: imgstr+="INTENSITY"; break; + case Image::FORMAT_GRAYSCALE_ALPHA: imgstr+="GRAYSCALE_ALPHA"; break; + case Image::FORMAT_RGB: imgstr+="RGB"; break; + case Image::FORMAT_RGBA: imgstr+="RGBA"; break; + case Image::FORMAT_INDEXED : imgstr+="INDEXED"; break; + case Image::FORMAT_INDEXED_ALPHA: imgstr+="INDEXED_ALPHA"; break; + case Image::FORMAT_BC1: imgstr+="BC1"; break; + case Image::FORMAT_BC2: imgstr+="BC2"; break; + case Image::FORMAT_BC3: imgstr+="BC3"; break; + case Image::FORMAT_BC4: imgstr+="BC4"; break; + case Image::FORMAT_BC5: imgstr+="BC5"; break; + case Image::FORMAT_PVRTC2: imgstr+="PVRTC2"; break; + case Image::FORMAT_PVRTC2_ALPHA: imgstr+="PVRTC2_ALPHA"; break; + case Image::FORMAT_PVRTC4: imgstr+="PVRTC4"; break; + case Image::FORMAT_PVRTC4_ALPHA: imgstr+="PVRTC4_ALPHA"; break; + case Image::FORMAT_ETC: imgstr+="ETC"; break; + case Image::FORMAT_ATC: imgstr+="ATC"; break; + case Image::FORMAT_ATC_ALPHA_EXPLICIT: imgstr+="ATC_ALPHA_EXPLICIT"; break; + case Image::FORMAT_ATC_ALPHA_INTERPOLATED: imgstr+="ATC_ALPHA_INTERPOLATED"; break; + case Image::FORMAT_CUSTOM: imgstr+="CUSTOM"; break; + default: {} + } + + + String s; + + DVector data = img.get_data(); + int len = data.size(); + DVector::Read r = data.read(); + const uint8_t *ptr=r.ptr();; + for (int i=0;i>4], hex[byte&0xF], 0}; + s+=str; + } + + imgstr+=", "; + f->store_string(imgstr); + f->store_string(s); + f->store_string(" )"); + } break; + case Variant::NODE_PATH: { + + String str=p_property; + + str="NodePath(\""+str.c_escape()+"\")"; + f->store_string(str); + + } break; + + case Variant::OBJECT: { + + RES res = p_property; + if (res.is_null()) { + f->store_string("null"); + if (r_ok) + *r_ok=true; + + break; // don't save it + } + + if (external_resources.has(res)) { + + f->store_string("ExtResource( "+itos(external_resources[res]+1)+" )"); + } else { + + if (internal_resources.has(res)) { + f->store_string("SubResource( "+itos(internal_resources[res])+" )"); + } else if (res->get_path().length() && res->get_path().find("::")==-1) { + + //external resource + String path=relative_paths?local_path.path_to_file(res->get_path()):res->get_path(); + f->store_string("Resource( \""+path+"\" )"); + } else { + f->store_string("null"); + ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); + ERR_BREAK(true); + //internal resource + } + } + + } break; + case Variant::INPUT_EVENT: { + + f->store_string("InputEvent()"); //will be added later + } break; + case Variant::DICTIONARY: { + + Dictionary dict = p_property; + + List keys; + dict.get_key_list(&keys); + keys.sort(); + + f->store_string("{ "); + for(List::Element *E=keys.front();E;E=E->next()) { + + //if (!_check_type(dict[E->get()])) + // continue; + bool ok; + write_property("",E->get(),&ok); + ERR_CONTINUE(!ok); + + f->store_string(":"); + write_property("",dict[E->get()],&ok); + if (!ok) + write_property("",Variant()); //at least make the file consistent.. + if (E->next()) + f->store_string(", "); + } + + + f->store_string(" }"); + + + } break; + case Variant::ARRAY: { + + f->store_string("[ "); + Array array = p_property; + int len=array.size(); + for (int i=0;i0) + f->store_string(", "); + write_property("",array[i]); + + + } + f->store_string(" ]"); + + } break; + + case Variant::RAW_ARRAY: { + + f->store_string("RawArray( "); + String s; + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const uint8_t *ptr=r.ptr();; + for (int i=0;i0) + f->store_string(", "); + uint8_t byte = ptr[i]; + const char hex[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + char str[3]={ hex[byte>>4], hex[byte&0xF], 0}; + f->store_string(str); + + } + + f->store_string(" )"); + + } break; + case Variant::INT_ARRAY: { + + f->store_string("IntArray( "); + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const int *ptr=r.ptr();; + + for (int i=0;i0) + f->store_string(", "); + + f->store_string(itos(ptr[i])); + } + + + f->store_string(" )"); + + } break; + case Variant::REAL_ARRAY: { + + f->store_string("FloatArray( "); + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const real_t *ptr=r.ptr();; + + for (int i=0;i0) + f->store_string(", "); + f->store_string(rtoss(ptr[i])); + } + + f->store_string(" )"); + + } break; + case Variant::STRING_ARRAY: { + + f->store_string("StringArray( "); + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const String *ptr=r.ptr();; + String s; + //write_string("\n"); + + + + for (int i=0;i0) + f->store_string(", "); + String str=ptr[i]; + f->store_string(""+str.c_escape()+"\""); + } + + f->store_string(" )"); + + } break; + case Variant::VECTOR2_ARRAY: { + + f->store_string("Vector2Array( "); + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const Vector2 *ptr=r.ptr();; + + for (int i=0;i0) + f->store_string(", "); + f->store_string(rtoss(ptr[i].x)+", "+rtoss(ptr[i].y) ); + } + + f->store_string(" )"); + + } break; + case Variant::VECTOR3_ARRAY: { + + f->store_string("Vector3Array( "); + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const Vector3 *ptr=r.ptr();; + + for (int i=0;i0) + f->store_string(", "); + f->store_string(rtoss(ptr[i].x)+", "+rtoss(ptr[i].y)+", "+rtoss(ptr[i].z) ); + } + + f->store_string(" )"); + + } break; + case Variant::COLOR_ARRAY: { + + f->store_string("ColorArray( "); + + DVector data = p_property; + int len = data.size(); + DVector::Read r = data.read(); + const Color *ptr=r.ptr();; + + for (int i=0;i0) + f->store_string(", "); + + f->store_string(rtoss(ptr[i].r)+", "+rtoss(ptr[i].g)+", "+rtoss(ptr[i].b)+", "+rtoss(ptr[i].a) ); + + } + f->store_string(" )"); + + } break; + default: {} + + } + + if (r_ok) + *r_ok=true; + +} + + +void ResourceFormatSaverTextInstance::_find_resources(const Variant& p_variant,bool p_main) { + + + switch(p_variant.get_type()) { + case Variant::OBJECT: { + + + RES res = p_variant.operator RefPtr(); + + if (res.is_null() || external_resources.has(res)) + return; + + if (!p_main && (!bundle_resources ) && res->get_path().length() && res->get_path().find("::") == -1 ) { + int index = external_resources.size(); + external_resources[res]=index; + return; + } + + if (resource_set.has(res)) + return; + + List property_list; + + res->get_property_list( &property_list ); + property_list.sort(); + + List::Element *I=property_list.front(); + + while(I) { + + PropertyInfo pi=I->get(); + + if (pi.usage&PROPERTY_USAGE_STORAGE || (bundle_resources && pi.usage&PROPERTY_USAGE_BUNDLE)) { + + Variant v=res->get(I->get().name); + _find_resources(v); + } + + I=I->next(); + } + + resource_set.insert( res ); //saved after, so the childs it needs are available when loaded + saved_resources.push_back(res); + + } break; + case Variant::ARRAY: { + + Array varray=p_variant; + int len=varray.size(); + for(int i=0;i keys; + d.get_key_list(&keys); + for(List::Element *E=keys.front();E;E=E->next()) { + + Variant v = d[E->get()]; + _find_resources(v); + } + } break; + default: {} + } + +} + + + +Error ResourceFormatSaverTextInstance::save(const String &p_path,const RES& p_resource,uint32_t p_flags) { + + if (p_path.ends_with(".tscn")) { + packed_scene=p_resource; + } + + Error err; + f = FileAccess::open(p_path, FileAccess::WRITE,&err); + ERR_FAIL_COND_V( err, ERR_CANT_OPEN ); + FileAccessRef _fref(f); + + local_path = Globals::get_singleton()->localize_path(p_path); + + relative_paths=p_flags&ResourceSaver::FLAG_RELATIVE_PATHS; + skip_editor=p_flags&ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES; + bundle_resources=p_flags&ResourceSaver::FLAG_BUNDLE_RESOURCES; + takeover_paths=p_flags&ResourceSaver::FLAG_REPLACE_SUBRESOURCE_PATHS; + if (!p_path.begins_with("res://")) { + takeover_paths=false; + } + + // save resources + _find_resources(p_resource,true); + + if (packed_scene.is_valid()) { + //add instances to external resources if saving a packed scene + for(int i=0;iget_state()->get_node_count();i++) { + Ref instance=packed_scene->get_state()->get_node_instance(i); + if (instance.is_valid() && !external_resources.has(instance)) { + int index = external_resources.size(); + external_resources[instance]=index; + } + } + } + + + ERR_FAIL_COND_V(err!=OK,err); + + { + String title=packed_scene.is_valid()?"[gd_scene ":"[gd_resource "; + if (packed_scene.is_null()) + title+="type=\""+p_resource->get_type()+"\" "; + int load_steps=saved_resources.size()+external_resources.size(); + //if (packed_scene.is_valid()) { + // load_steps+=packed_scene->get_node_count(); + //} + //no, better to not use load steps from nodes, no point to that + + if (load_steps>1) { + title+="load_steps="+itos(load_steps)+" "; + } + title+="format="+itos(FORMAT_VERSION)+""; + //title+="engine_version=\""+itos(VERSION_MAJOR)+"."+itos(VERSION_MINOR)+"\""; + + f->store_string(title); + f->store_line("]\n"); //one empty line + } + + + for(Map::Element *E=external_resources.front();E;E=E->next()) { + + String p = E->key()->get_path(); + + f->store_string("[ext_resource path=\""+p+"\" type=\""+E->key()->get_save_type()+"\" id="+itos(E->get()+1)+"]\n"); //bundled + } + + if (external_resources.size()) + f->store_line(String()); //separate + + Set used_indices; + + for(List::Element *E=saved_resources.front();E;E=E->next()) { + + RES res = E->get(); + if (E->next() && (res->get_path()=="" || res->get_path().find("::") != -1 )) { + + if (res->get_subindex()!=0) { + if (used_indices.has(res->get_subindex())) { + res->set_subindex(0); //repeated + } else { + used_indices.insert(res->get_subindex()); + } + } + } + } + + for(List::Element *E=saved_resources.front();E;E=E->next()) { + + RES res = E->get(); + ERR_CONTINUE(!resource_set.has(res)); + bool main = (E->next()==NULL); + + if (main && packed_scene.is_valid()) + break; //save as a scene + + if (main) { + f->store_line("[resource]\n"); + } else { + String line="[sub_resource "; + if (res->get_subindex()==0) { + int new_subindex=1; + if (used_indices.size()) { + new_subindex=used_indices.back()->get()+1; + } + + res->set_subindex(new_subindex); + used_indices.insert(new_subindex); + } + + int idx = res->get_subindex(); + line+="type=\""+res->get_type()+"\" id="+itos(idx); + f->store_line(line+"]\n"); + if (takeover_paths) { + res->set_path(p_path+"::"+itos(idx),true); + } + + internal_resources[res]=idx; + + } + + + List property_list; + res->get_property_list(&property_list); +// property_list.sort(); + for(List::Element *PE = property_list.front();PE;PE=PE->next()) { + + + if (skip_editor && PE->get().name.begins_with("__editor")) + continue; + + if (PE->get().usage&PROPERTY_USAGE_STORAGE || (bundle_resources && PE->get().usage&PROPERTY_USAGE_BUNDLE)) { + + String name = PE->get().name; + Variant value = res->get(name); + + + if ((PE->get().usage&PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero())||(PE->get().usage&PROPERTY_USAGE_STORE_IF_NONONE && value.is_one()) ) + continue; + + if (PE->get().type==Variant::OBJECT && value.is_zero()) + continue; + + write_property(name,value); + f->store_string("\n"); + } + + + } + + f->store_string("\n"); + + } + + if (packed_scene.is_valid()) { + //if this is a scene, save nodes and connections! + Ref state = packed_scene->get_state(); + for(int i=0;iget_node_count();i++) { + + StringName type = state->get_node_type(i); + StringName name = state->get_node_name(i); + NodePath path = state->get_node_path(i,true); + NodePath owner = state->get_node_owner_path(i); + Ref instance = state->get_node_instance(i); + Vector groups = state->get_node_groups(i); + + String header="[node"; + header+=" name=\""+String(name)+"\""; + if (type!=StringName()) { + header+=" type=\""+String(type)+"\""; + } + if (path!=NodePath()) { + header+=" parent=\""+String(path.simplified())+"\""; + } + if (owner!=NodePath() && owner!=NodePath(".")) { + header+=" owner=\""+String(owner.simplified())+"\""; + } + + if (groups.size()) { + String sgroups=" groups=[ "; + for(int j=0;j0) + sgroups+=", "; + sgroups+="\""+groups[i].operator String().c_escape()+"\""; + } + sgroups+=" ]"; + header+=sgroups; + } + + f->store_string(header); + + if (instance.is_valid()) { + f->store_string(" instance="); + write_property("",instance); + } + + f->store_line("]\n"); + + for(int j=0;jget_node_property_count(i);j++) { + + write_property(state->get_node_property_name(i,j),state->get_node_property_value(i,j)); + f->store_line(String()); + + } + + if (state->get_node_property_count(i)) { + //add space + f->store_line(String()); + } + + } + + for(int i=0;iget_connection_count();i++) { + + String connstr="[connection"; + connstr+=" signal=\""+String(state->get_connection_signal(i))+"\""; + connstr+=" from=\""+String(state->get_connection_source(i).simplified())+"\""; + connstr+=" to=\""+String(state->get_connection_target(i).simplified())+"\""; + connstr+=" method=\""+String(state->get_connection_method(i))+"\""; + int flags = state->get_connection_flags(i); + if (flags!=Object::CONNECT_PERSIST) { + connstr+=" flags="+itos(flags); + } + + Array binds=state->get_connection_binds(i); + f->store_string(connstr); + if (binds.size()) { + f->store_string(" binds="); + write_property("",binds); + } + + f->store_line("]\n"); + } + + f->store_line(String()); + + Vector editable_instances = state->get_editable_instances(); + for(int i=0;istore_line("[editable path=\""+editable_instances[i].operator String()+"\"]"); + } + } + + if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) { + f->close(); + return ERR_CANT_CREATE; + } + + f->close(); + //memdelete(f); + + return OK; +} + + + +Error ResourceFormatSaverText::save(const String &p_path,const RES& p_resource,uint32_t p_flags) { + + if (p_path.ends_with(".sct") && p_resource->get_type()!="PackedScene") { + return ERR_FILE_UNRECOGNIZED; + } + + ResourceFormatSaverTextInstance saver; + return saver.save(p_path,p_resource,p_flags); + +} + +bool ResourceFormatSaverText::recognize(const RES& p_resource) const { + + + return true; // all recognized! +} +void ResourceFormatSaverText::get_recognized_extensions(const RES& p_resource,List *p_extensions) const { + + p_extensions->push_back("tres"); //text resource + if (p_resource->get_type()=="PackedScene") + p_extensions->push_back("tscn"); //text scene + +} + +ResourceFormatSaverText* ResourceFormatSaverText::singleton=NULL; +ResourceFormatSaverText::ResourceFormatSaverText() { + singleton=this; +} diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h new file mode 100644 index 0000000000..576a78d183 --- /dev/null +++ b/scene/resources/scene_format_text.h @@ -0,0 +1,46 @@ +#ifndef SCENE_FORMAT_TEXT_H +#define SCENE_FORMAT_TEXT_H + +#include "io/resource_loader.h" +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "scene/resources/packed_scene.h" + +class ResourceFormatSaverTextInstance { + + String local_path; + + Ref packed_scene; + + bool takeover_paths; + bool relative_paths; + bool bundle_resources; + bool skip_editor; + FileAccess *f; + Set resource_set; + List saved_resources; + Map external_resources; + Map internal_resources; + + void _find_resources(const Variant& p_variant,bool p_main=false); + void write_property(const String& p_name,const Variant& p_property,bool *r_ok=NULL); + +public: + + Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0); + + +}; + +class ResourceFormatSaverText : public ResourceFormatSaver { +public: + static ResourceFormatSaverText* singleton; + virtual Error save(const String &p_path,const RES& p_resource,uint32_t p_flags=0); + virtual bool recognize(const RES& p_resource) const; + virtual void get_recognized_extensions(const RES& p_resource,List *p_extensions) const; + + ResourceFormatSaverText(); +}; + + +#endif // SCENE_FORMAT_TEXT_H diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index fb3c7d5d18..1b709df7d8 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -1107,6 +1107,11 @@ void EditorNode::_dialog_action(String p_file) { push_item(res.operator->() ); } break; + case FILE_NEW_INHERITED_SCENE: { + + + load_scene(p_file,false,true); + } break; case FILE_OPEN_SCENE: { @@ -1930,6 +1935,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { } break; + case FILE_NEW_INHERITED_SCENE: case FILE_OPEN_SCENE: { @@ -1950,7 +1956,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) { if (scene) { file->set_current_path(scene->get_filename()); }; - file->set_title("Open Scene"); + file->set_title(p_option==FILE_OPEN_SCENE?"Open Scene":"Open Base Scene"); file->popup_centered_ratio(); } break; @@ -3311,7 +3317,7 @@ void EditorNode::fix_dependencies(const String& p_for_file) { dependency_fixer->edit(p_for_file); } -Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) { +Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bool p_set_inherited) { if (!is_inside_tree()) { defer_load_scene = p_scene; @@ -3441,6 +3447,13 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps) { } */ + if (p_set_inherited) { + Ref state = sdata->get_state(); + state->set_path(lpath); + new_scene->set_scene_inherited_state(state); + } + + set_edited_scene(new_scene); _get_scene_metadata(); /* @@ -4793,6 +4806,7 @@ EditorNode::EditorNode() { file_menu->set_tooltip("Operations with scene files."); p=file_menu->get_popup(); p->add_item("New Scene",FILE_NEW_SCENE); + p->add_item("New Inherited Scene..",FILE_NEW_INHERITED_SCENE); p->add_item("Open Scene..",FILE_OPEN_SCENE,KEY_MASK_CMD+KEY_O); p->add_separator(); p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S); diff --git a/tools/editor/editor_node.h b/tools/editor/editor_node.h index 53e16d9c58..d52e08191d 100644 --- a/tools/editor/editor_node.h +++ b/tools/editor/editor_node.h @@ -107,6 +107,7 @@ class EditorNode : public Node { enum MenuOptions { FILE_NEW_SCENE, + FILE_NEW_INHERITED_SCENE, FILE_OPEN_SCENE, FILE_SAVE_SCENE, FILE_SAVE_AS_SCENE, @@ -565,7 +566,7 @@ public: void fix_dependencies(const String& p_for_file); void clear_scene() { _cleanup_scene(); } - Error load_scene(const String& p_scene,bool p_ignore_broken_deps=false); + Error load_scene(const String& p_scene, bool p_ignore_broken_deps=false, bool p_set_inherited=false); Error load_resource(const String& p_scene); bool is_scene_open(const String& p_path); diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp index b513e32c13..1a07f30e4e 100644 --- a/tools/editor/property_editor.cpp +++ b/tools/editor/property_editor.cpp @@ -42,6 +42,8 @@ #include "multi_node_edit.h" #include "array_property_edit.h" #include "editor_help.h" +#include "scene/resources/packed_scene.h" + void CustomPropertyEditor::_notification(int p_what) { @@ -1655,25 +1657,101 @@ CustomPropertyEditor::CustomPropertyEditor() { menu->connect("item_pressed",this,"_menu_option"); } +bool PropertyEditor::_might_be_in_instance() { - -Node *PropertyEditor::get_instanced_node() { - - //this sucks badly if (!obj) return NULL; Node *node = obj->cast_to(); + + Node* edited_scene =EditorNode::get_singleton()->get_edited_scene(); + + bool might_be=false; + + while(node) { + + if (node->get_scene_instance_state().is_valid()) { + might_be=true; + break; + } + if (node==edited_scene) { + if (node->get_scene_inherited_state().is_valid()) { + might_be=true; + break; + } + might_be=false; + break; + } + node=node->get_owner(); + } + + return might_be; + +} + +bool PropertyEditor::_get_instanced_node_original_property(const StringName& p_prop,Variant& value) { + + Node *node = obj->cast_to(); + if (!node) - return NULL; + return false; - if (node->get_filename()=="") - return NULL; + Node *orig=node; + + Node* edited_scene =EditorNode::get_singleton()->get_edited_scene(); + + bool found=false; - if (!node->get_owner()) - return NULL; //scene root i guess +// print_line("for prop - "+String(p_prop)); - return node; + while(node) { + + Ref ss; + + if (node==edited_scene) { + ss=node->get_scene_inherited_state(); + } else { + ss=node->get_scene_instance_state(); + } +// print_line("at - "+String(edited_scene->get_path_to(node))); + + if (ss.is_valid()) { + NodePath np = node->get_path_to(orig); + int node_idx = ss->find_node_by_path(np); +// print_line("\t valid, nodeidx "+itos(node_idx)); + if (node_idx>=0) { + bool lfound=false; + Variant lvar; + lvar=ss->get_property_value(node_idx,p_prop,lfound); + if (lfound) { + found=true; + value=lvar; +// print_line("\t found value "+String(value)); + } + } + } + if (node==edited_scene) { + //just in case + break; + } + node=node->get_owner(); + + } + + return found; +} + +bool PropertyEditor::_is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage) { + + if (p_orig.get_type()==Variant::NIL) { + //special cases + if (p_current.is_zero() && p_usage&PROPERTY_USAGE_STORE_IF_NONZERO) + return false; + if (p_current.is_one() && p_usage&PROPERTY_USAGE_STORE_IF_NONONE) + return false; + } + + return bool(Variant::evaluate(Variant::OP_NOT_EQUAL,p_current,p_orig)); } TreeItem *PropertyEditor::find_item(TreeItem *p_item,const String& p_name) { @@ -1910,6 +1988,8 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p } + + void PropertyEditor::_notification(int p_what) { if (p_what==NOTIFICATION_ENTER_TREE) { @@ -1950,12 +2030,16 @@ void PropertyEditor::_notification(int p_what) { if (!item) continue; - if (get_instanced_node()) { + if (_might_be_in_instance()) { + + + Variant vorig; + Dictionary d=item->get_metadata(0); + int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0; - Dictionary d = get_instanced_node()->get_instance_state(); - if (d.has(*k)) { + + if (_get_instanced_node_original_property(*k,vorig) || usage) { Variant v = obj->get(*k); - Variant vorig = d[*k]; int found=-1; for(int i=0;iget_button_count(1);i++) { @@ -1966,7 +2050,7 @@ void PropertyEditor::_notification(int p_what) { } } - bool changed = ! (v==vorig); + bool changed = _is_property_different(v,vorig,usage); if ((found!=-1)!=changed) { @@ -2049,12 +2133,14 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) { if (name!=String()) { - if (get_instanced_node()) { + if (_might_be_in_instance()) { + + Variant vorig; + Dictionary d=p_item->get_metadata(0); + int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0; - Dictionary d = get_instanced_node()->get_instance_state(); - if (d.has(name)) { + if (_get_instanced_node_original_property(name,vorig) || usage) { Variant v = obj->get(name); - Variant vorig = d[name]; int found=-1; for(int i=0;iget_button_count(1);i++) { @@ -2065,7 +2151,7 @@ void PropertyEditor::_refresh_item(TreeItem *p_item) { } } - bool changed = ! (v==vorig); + bool changed = _is_property_different(v,vorig,usage); if ((found!=-1)!=changed) { @@ -2326,7 +2412,8 @@ void PropertyEditor::update_tree() { d["type"]=(int)p.type; d["hint"]=(int)p.hint; d["hint_text"]=p.hint_string; - + d["usage"]=(int)p.usage; + item->set_metadata( 0, d ); item->set_metadata( 1, p.name ); @@ -2777,14 +2864,17 @@ void PropertyEditor::update_tree() { } } - if (get_instanced_node()) { + if (_might_be_in_instance()) { - Dictionary d = get_instanced_node()->get_instance_state(); - if (d.has(p.name)) { + Variant vorig; + Dictionary d=item->get_metadata(0); + int usage = d.has("usage")?int(int(d["usage"])&(PROPERTY_USAGE_STORE_IF_NONONE|PROPERTY_USAGE_STORE_IF_NONZERO)):0; + if (_get_instanced_node_original_property(p.name,vorig) || usage) { Variant v = obj->get(p.name); - Variant vorig = d[p.name]; - if (! (v==vorig)) { + + if (_is_property_different(v,vorig,usage)) { + //print_line("FOR "+String(p.name)+" RELOAD WITH: "+String(v)+"("+Variant::get_type_name(v.get_type())+")=="+String(vorig)+"("+Variant::get_type_name(vorig.get_type())+")"); item->add_button(1,get_icon("Reload","EditorIcons"),3); } } @@ -3081,17 +3171,18 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) { call_deferred("_set_range_def",ti,prop,ti->get_range(p_column)+1.0); } else if (p_button==3) { - if (!get_instanced_node()) + if (!_might_be_in_instance()) return; if (!d.has("name")) return; String prop=d["name"]; - Dictionary d2 = get_instanced_node()->get_instance_state(); - if (d2.has(prop)) { + Variant vorig; + + if (_get_instanced_node_original_property(prop,vorig)) { - _edit_set(prop,d2[prop]); + _edit_set(prop,vorig); } } else { diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h index 36ecc794ed..9686bf0bd7 100644 --- a/tools/editor/property_editor.h +++ b/tools/editor/property_editor.h @@ -121,6 +121,7 @@ class CustomPropertyEditor : public Popup { void show_value_editors(int p_amount); void config_value_editors(int p_amount, int p_columns,int p_label_w,const List& p_strings); void config_action_buttons(const List& p_strings); + protected: void _notification(int p_what); @@ -184,13 +185,17 @@ class PropertyEditor : public Control { virtual void _changed_callback(Object *p_changed,const char * p_what); virtual void _changed_callbacks(Object *p_changed,const String& p_callback); + void _edit_button(Object *p_item, int p_column, int p_button); void _node_removed(Node *p_node); void _edit_set(const String& p_name, const Variant& p_value); void _draw_flags(Object *ti,const Rect2& p_rect); - Node *get_instanced_node(); + bool _might_be_in_instance(); + bool _get_instanced_node_original_property(const StringName& p_prop,Variant& value); + bool _is_property_different(const Variant& p_current, const Variant& p_orig,int p_usage=0); + void _refresh_item(TreeItem *p_item); void _set_range_def(Object *p_item, String prop, float p_frame); diff --git a/tools/editor/reparent_dialog.cpp b/tools/editor/reparent_dialog.cpp index 6d0c5b867e..78ba47d54b 100644 --- a/tools/editor/reparent_dialog.cpp +++ b/tools/editor/reparent_dialog.cpp @@ -103,6 +103,7 @@ ReparentDialog::ReparentDialog() { add_child(node_only); node_only->hide(); + tree->set_show_enabled_subscene(true); //vbc->add_margin_child("Options:",node_only);; diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp index 276f2dea33..920ab599e9 100644 --- a/tools/editor/scene_tree_dock.cpp +++ b/tools/editor/scene_tree_dock.cpp @@ -36,8 +36,8 @@ #include "script_editor_debugger.h" #include "tools/editor/plugins/script_editor_plugin.h" #include "multi_node_edit.h" -void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { +void SceneTreeDock::_unhandled_key_input(InputEvent p_event) { uint32_t sc = p_event.key.get_scancode_with_modifiers(); if (!p_event.key.pressed || p_event.key.echo) @@ -71,7 +71,7 @@ Node* SceneTreeDock::instance(const String& p_file) { Node*instanced_scene=NULL; Ref sdata = ResourceLoader::load(p_file); if (sdata.is_valid()) - instanced_scene=sdata->instance(); + instanced_scene=sdata->instance(true); if (!instanced_scene) { @@ -96,7 +96,7 @@ Node* SceneTreeDock::instance(const String& p_file) { } } - instanced_scene->generate_instance_state(); + //instanced_scene->generate_instance_state(); instanced_scene->set_filename( Globals::get_singleton()->localize_path(p_file) ); editor_data->get_undo_redo().create_action("Instance Scene"); @@ -158,8 +158,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { case TOOL_NEW: { - if (!_validate_no_foreign()) - break; + //if (!_validate_no_foreign()) + // break; create_dialog->popup_centered_ratio(); } break; case TOOL_INSTANCE: { @@ -176,8 +176,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { break; } - if (!_validate_no_foreign()) - break; + //if (!_validate_no_foreign()) + // break; file->set_mode(EditorFileDialog::MODE_OPEN_FILE); List extensions; @@ -202,8 +202,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (!current) break; - if (!_validate_no_foreign()) - break; + //if (!_validate_no_foreign()) + // break; connect_dialog->popup_centered_ratio(); connect_dialog->set_node(current); @@ -213,8 +213,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *current = scene_tree->get_selected(); if (!current) break; - if (!_validate_no_foreign()) - break; + //if (!_validate_no_foreign()) + // break; groups_editor->set_current(current); groups_editor->popup_centered_ratio(); } break; @@ -224,8 +224,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { if (!selected) break; - if (!_validate_no_foreign()) - break; + //if (!_validate_no_foreign()) + // break; Ref