diff options
36 files changed, 1293 insertions, 309 deletions
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h index b1e0066c35..409543bf25 100644 --- a/core/command_queue_mt.h +++ b/core/command_queue_mt.h @@ -152,6 +152,23 @@ class CommandQueueMT { virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); } }; + template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class P8> + struct Command8 : public CommandBase { + + T*instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + + virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7,p8); } + }; + /* comands that return */ template<class T,class M,class R> @@ -270,6 +287,25 @@ class CommandQueueMT { virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; } }; + template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class P8,class R> + struct CommandRet8 : public CommandBase { + + T*instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + R* ret; + SyncSemaphore *sync; + + virtual void call() { *ret = (instance->*method)(p1,p2,p3,p4,p5,p6,p7,p8); sync->sem->post(); sync->in_use=false; ; } + }; + /** commands that don't return but sync */ /* comands that return */ @@ -390,6 +426,25 @@ class CommandQueueMT { virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7); sync->sem->post(); sync->in_use=false; ; } }; + template<class T,class M,class P1,class P2,class P3,class P4,class P5,class P6,class P7,class P8> + struct CommandSync8 : public CommandBase { + + T*instance; + M method; + typename GetSimpleTypeT<P1>::type_t p1; + typename GetSimpleTypeT<P2>::type_t p2; + typename GetSimpleTypeT<P3>::type_t p3; + typename GetSimpleTypeT<P4>::type_t p4; + typename GetSimpleTypeT<P5>::type_t p5; + typename GetSimpleTypeT<P6>::type_t p6; + typename GetSimpleTypeT<P7>::type_t p7; + typename GetSimpleTypeT<P8>::type_t p8; + + SyncSemaphore *sync; + + virtual void call() { (instance->*method)(p1,p2,p3,p4,p5,p6,p7,p8); sync->sem->post(); sync->in_use=false; ; } + }; + /***** BASE *******/ enum { @@ -639,6 +694,27 @@ public: if (sync) sync->post(); } + + template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7,class P8> + void push( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8 ) { + + Command8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> * cmd = allocate_and_lock< Command8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> >(); + + cmd->instance=p_instance; + cmd->method=p_method; + cmd->p1=p1; + cmd->p2=p2; + cmd->p3=p3; + cmd->p4=p4; + cmd->p5=p5; + cmd->p6=p6; + cmd->p7=p7; + cmd->p8=p8; + + unlock(); + + if (sync) sync->post(); + } /*** PUSH AND RET COMMANDS ***/ @@ -806,6 +882,31 @@ public: ss->sem->wait(); } + template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class P8,class R> + void push_and_ret( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7,P8 p8, R* r_ret ) { + + CommandRet8<T,M,P1,P2,P3,P4,P5,P6,P7,P8,R> * cmd = allocate_and_lock< CommandRet8<T,M,P1,P2,P3,P4,P5,P6,P7,P8,R> >(); + + cmd->instance=p_instance; + cmd->method=p_method; + cmd->p1=p1; + cmd->p2=p2; + cmd->p3=p3; + cmd->p4=p4; + cmd->p5=p5; + cmd->p6=p6; + cmd->p7=p7; + cmd->p8=p8; + cmd->ret=r_ret; + SyncSemaphore *ss=_alloc_sync_sem(); + cmd->sync=ss; + + unlock(); + + if (sync) sync->post(); + ss->sem->wait(); + } + template<class T, class M> void push_and_sync( T * p_instance, M p_method) { @@ -971,6 +1072,31 @@ public: ss->sem->wait(); } + template<class T, class M, class P1, class P2, class P3, class P4, class P5, class P6,class P7,class P8> + void push_and_sync( T * p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6,P7 p7,P8 p8) { + + CommandSync8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> * cmd = allocate_and_lock< CommandSync8<T,M,P1,P2,P3,P4,P5,P6,P7,P8> >(); + + cmd->instance=p_instance; + cmd->method=p_method; + cmd->p1=p1; + cmd->p2=p2; + cmd->p3=p3; + cmd->p4=p4; + cmd->p5=p5; + cmd->p6=p6; + cmd->p7=p7; + cmd->p8=p8; + + SyncSemaphore *ss=_alloc_sync_sem(); + cmd->sync=ss; + + unlock(); + + if (sync) sync->post(); + ss->sem->wait(); + } + void wait_and_flush_one() { ERR_FAIL_COND(!sync); sync->wait(); diff --git a/core/dictionary.cpp b/core/dictionary.cpp index 75c8531251..6204a87054 100644 --- a/core/dictionary.cpp +++ b/core/dictionary.cpp @@ -199,6 +199,18 @@ Array Dictionary::keys() const { } +Array Dictionary::values() const { + + Array varr; + varr.resize(size()); + const Variant *key=NULL; + int i=0; + while((key=next(key))){ + varr[i++] = _p->variant_map[*key]; + } + return varr; +} + const Variant* Dictionary::next(const Variant* p_key) const { return _p->variant_map.next(p_key); @@ -250,5 +262,3 @@ Dictionary::~Dictionary() { _unref(); } - - diff --git a/core/dictionary.h b/core/dictionary.h index c854e95ee6..ae79fab9c3 100644 --- a/core/dictionary.h +++ b/core/dictionary.h @@ -81,6 +81,7 @@ public: const Variant* next(const Variant* p_key=NULL) const; Array keys() const; + Array values() const; Dictionary(const Dictionary& p_from); Dictionary(bool p_shared=false); diff --git a/core/dvector.h b/core/dvector.h index fbb1fc4824..a5519ed604 100644 --- a/core/dvector.h +++ b/core/dvector.h @@ -285,6 +285,7 @@ public: Error resize(int p_size); + void invert(); void operator=(const DVector& p_dvector) { reference(p_dvector); } DVector() {} @@ -424,6 +425,18 @@ Error DVector<T>::resize(int p_size) { return OK; } +template<class T> +void DVector<T>::invert() { + T temp; + Write w = write(); + int s = size(); + int half_s = s/2; + for(int i=0;i<half_s;i++) { + temp = w[i]; + w[i] = w[s-i-1]; + w[s-i-1] = temp; + } +} #endif diff --git a/core/global_constants.cpp b/core/global_constants.cpp index 3cf4ff8f83..63764383ff 100644 --- a/core/global_constants.cpp +++ b/core/global_constants.cpp @@ -478,7 +478,21 @@ static _GlobalConstant _global_constants[]={ BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORAGE ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR ), BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NETWORK ), + + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_EDITOR_HELPER ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CHECKABLE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CHECKED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_INTERNATIONALIZED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_BUNDLE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_CATEGORY ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONZERO ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_STORE_IF_NONONE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NO_INSTANCE_STATE ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_RESTART_IF_CHANGED ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_DEFAULT_INTL ), + BIND_GLOBAL_CONSTANT( PROPERTY_USAGE_NOEDITOR ), BIND_GLOBAL_CONSTANT( METHOD_FLAG_NORMAL ), BIND_GLOBAL_CONSTANT( METHOD_FLAG_EDITOR ), diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index b547dc0e85..1bb80e74eb 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -319,7 +319,11 @@ Ref<ResourceInteractiveLoader> ResourceLoader::load_interactive(const String &p_ if (OS::get_singleton()->is_stdout_verbose()) print_line("load resource: "+local_path+" (cached)"); - return RES( ResourceCache::get(local_path ) ); + Ref<Resource> res_cached = ResourceCache::get(local_path); + Ref<ResourceInteractiveLoaderDefault> ril = Ref<ResourceInteractiveLoaderDefault>(memnew(ResourceInteractiveLoaderDefault)); + + ril->resource = res_cached; + return ril; } if (OS::get_singleton()->is_stdout_verbose()) diff --git a/core/variant_call.cpp b/core/variant_call.cpp index f5dcd75691..eb3ab65f40 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -262,7 +262,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM0R(String,basename); VCALL_LOCALMEM1R(String,plus_file); VCALL_LOCALMEM1R(String,ord_at); - //VCALL_LOCALMEM2R(String,erase); + VCALL_LOCALMEM2(String,erase); VCALL_LOCALMEM0R(String,hash); VCALL_LOCALMEM0R(String,md5_text); VCALL_LOCALMEM0R(String,md5_buffer); @@ -339,6 +339,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1R(Vector2,reflect); VCALL_LOCALMEM0R(Vector2,angle); // VCALL_LOCALMEM1R(Vector2,cross); + VCALL_LOCALMEM0R(Vector2,abs); VCALL_LOCALMEM0R(Rect2,get_area); VCALL_LOCALMEM1R(Rect2,intersects); @@ -445,6 +446,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_LOCALMEM1(Dictionary,erase); VCALL_LOCALMEM0R(Dictionary,hash); VCALL_LOCALMEM0R(Dictionary,keys); + VCALL_LOCALMEM0R(Dictionary,values); VCALL_LOCALMEM1R(Dictionary,parse_json); VCALL_LOCALMEM0R(Dictionary,to_json); @@ -1284,7 +1286,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC0(STRING,STRING,String,basename,varray()); ADDFUNC1(STRING,STRING,String,plus_file,STRING,"file",varray()); ADDFUNC1(STRING,STRING,String,ord_at,INT,"at",varray()); -// ADDFUNC2(STRING,String,erase,INT,INT,varray()); + ADDFUNC2(STRING,NIL,String,erase,INT,"pos",INT,"chars", varray()); ADDFUNC0(STRING,INT,String,hash,varray()); ADDFUNC0(STRING,STRING,String,md5_text,varray()); ADDFUNC0(STRING,RAW_ARRAY,String,md5_buffer,varray()); @@ -1335,6 +1337,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(VECTOR2,VECTOR2,Vector2,slide,VECTOR2,"vec",varray()); ADDFUNC1(VECTOR2,VECTOR2,Vector2,reflect,VECTOR2,"vec",varray()); //ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray()); + ADDFUNC0(VECTOR2,VECTOR2,Vector2,abs,varray()); ADDFUNC0(RECT2,REAL,Rect2,get_area,varray()); ADDFUNC1(RECT2,BOOL,Rect2,intersects,RECT2,"b",varray()); @@ -1434,6 +1437,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(DICTIONARY,NIL,Dictionary,erase,NIL,"value",varray()); ADDFUNC0(DICTIONARY,INT,Dictionary,hash,varray()); ADDFUNC0(DICTIONARY,ARRAY,Dictionary,keys,varray()); + ADDFUNC0(DICTIONARY,ARRAY,Dictionary,values,varray()); ADDFUNC1(DICTIONARY,INT,Dictionary,parse_json,STRING,"json",varray()); ADDFUNC0(DICTIONARY,STRING,Dictionary,to_json,varray()); diff --git a/doc/base/classes.xml b/doc/base/classes.xml index 8f29c7f166..d329d5344f 100644 --- a/doc/base/classes.xml +++ b/doc/base/classes.xml @@ -9015,7 +9015,7 @@ </argument> <description> Change the anchor (ANCHOR_BEGIN, ANCHOR_END, ANCHOR_RATIO) type for a margin (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Changing the anchor mode converts the current margin offset from the previous anchor mode to the new one, so margin offsets ([method set_margin]) must be done after setting anchors, or at the same time ([method set_anchor_and_margin]) - + Additionally, [code]keep_margin[/code] controls whether margins should be left the same, or changed to keep the same position and size on-screen. </description> </method> @@ -10312,7 +10312,7 @@ This approximation makes straight segments between each point, then subdivides t <return type="Array"> </return> <description> - Return the list of keys in the dictionary. + Return the list of keys in the [Dictionary]. </description> </method> <method name="parse_json"> @@ -10338,6 +10338,13 @@ This approximation makes straight segments between each point, then subdivides t Return the dictionary as json text. </description> </method> + <method name="values"> + <return type="Array"> + </return> + <description> + Return the list of values in the [Dictionary]. + </description> + </method> </methods> <constants> </constants> @@ -10671,14 +10678,14 @@ This approximation makes straight segments between each point, then subdivides t This function is called for each file exported and depending from the return value one of many things might happen. - + 1) If returned value is null, the file is exported as is. - + 2) If the returned value is a RawAray (array of bytes), the content of that array becomes the new file being exported. - + 3) If the file must also change it's name when exported, then a [Dictionary] must be returned with two fields: 'name' with the new filename and 'data' @@ -10848,8 +10855,8 @@ This approximation makes straight segments between each point, then subdivides t </brief_description> <description> Import plugins make it easy to handle importing of external assets - into a project. - + into a project. + They way they work is not that obvious though, so please make sure to read the documentation, tutorials and examples. </description> @@ -10872,7 +10879,7 @@ This approximation makes straight segments between each point, then subdivides t when exported. The only exception is in some cases when the file must be re-imported for different platforms (ie. texture compression). - + If you want to customize the export process, it's recommended to use [EditorExportPlugin.custom_export] instead. @@ -10884,7 +10891,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Get the name of the import plugin, which will be used to identify content imported by this plugin. - + Try to use lowecase and underscores if possible. </description> </method> @@ -10909,23 +10916,23 @@ This approximation makes straight segments between each point, then subdivides t (from the dialog) or re-import (manual or automatic when external source files changed). - + An import process generally works like this: - + 1) Check the metadata for source files and options. Metadata is either generated in the import dialog or taken from an existing resource upon reimport. - + 2) Perform the import process into a new resource. Some times the resource being re-imported may be already loaded and in use, so checking for this by using [ResourceLoader.has] is recommended. Otherwise create a new resource. - + 3) Set the metadata from the argument into the existing or new resource being created using [Resource.set_import_metadata]. - + 4) Save the resource into 'path' (function argument) </description> </method> @@ -10938,12 +10945,12 @@ This approximation makes straight segments between each point, then subdivides t when the user chooses to re-import the resource (from filesystem). In the later case, the path for the existing file is supplied in the argument. - + If the path is supplied, it is recommended to read the import metadata with [ResourceLoader.load_import_metadata] and fill in the fields with the values contained there. - + The dialog can be shown in any way (just use a ConfirmationDialog and pop it up). Upon confirmation, fill up a ResourceImportMetadata and @@ -11000,8 +11007,8 @@ This approximation makes straight segments between each point, then subdivides t This method is called when the editor is about to save the project, switch to another tab, etc. It asks the plugin to apply any pending state changes - to ensure consistency. - + to ensure consistency. + This is used, for example, in shader editors to let the plugin know that it must apply the shader code being written by the user to the object. @@ -11045,7 +11052,7 @@ This approximation makes straight segments between each point, then subdivides t object type derived from CanvasItem to capture the input in the 2D editor viewport. The function is only being called if your object is being edited. - + Return true if you want to capture the input, otherwise false. </description> @@ -11062,11 +11069,11 @@ This approximation makes straight segments between each point, then subdivides t given objet type derived from Spatial to capture the input of the viewport. The function is only being called if your object is being edited. - + By using the [InputEvent] and the [Camera] arguments it's pretty easy to do raycasts into space using Camera functions. - + Return true if you want to capture the input, otherwise false. </description> @@ -11128,7 +11135,7 @@ This approximation makes straight segments between each point, then subdivides t This function will be called when the editor is requested to become visible. It is used for plugins that edit a specific object type. - + Remember that you have to manage the visibility of all your editor controls manually. </description> @@ -11149,11 +11156,11 @@ This approximation makes straight segments between each point, then subdivides t Add a custom control to a container (see CONTAINER_* enum). There are many locations where custom controls can be added in the editor UI. - + Please remember that you have to manage the visibility of your custom controls yourself (and likely hide it after adding it). - + If your plugin is being removed, also make sure to remove your custom controls too. </description> @@ -11166,7 +11173,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Add a control to the bottom panel (together with Output, Debug, Animation, etc). - + If your plugin is being removed, also make sure to remove your control by calling [method remove_control_from_bottom_panel]. @@ -11179,12 +11186,12 @@ This approximation makes straight segments between each point, then subdivides t </argument> <description> Add the control to a specific dock slot (see DOCK_* - enum for options). - + enum for options). + If the dock is repositioned and as long as the plugin is active, the editor will save the dock position on further sessions. - + If your plugin is being removed, also make sure to remove your control by calling [method remove_control_from_docks]. @@ -11221,16 +11228,16 @@ This approximation makes straight segments between each point, then subdivides t Add a custom type, which will appear in the list of nodes or resources. An icon can be optionally passed. - + When given node or resource is selected, the base type will be instanced (ie, "Spatial", "Control", "Resource"), then the script will be loaded and set to this object. - + You can use the [EditorPlugin.handles] to check if your custom object is being edited by checking the - script or using 'extends' keyword. - + script or using 'extends' keyword. + During run-time, this will be a simple object with a script so this function does not need to be called then. @@ -11251,7 +11258,7 @@ This approximation makes straight segments between each point, then subdivides t Add an import plugin. These plugins manage importing external content (from outside the project) into formats the engine can understand. - + On exit, don't forget to remove the plugin by calling [method remove_import_plugin] </description> @@ -11367,7 +11374,7 @@ This approximation makes straight segments between each point, then subdivides t <description> This function is called upon import with the imported scene. - + Just do any changes desired to the scene and return it. If null is returned, import will fail and throw an error to the user. @@ -11457,14 +11464,14 @@ This approximation makes straight segments between each point, then subdivides t <description> Object that holds the project-independent editor settings. These settings are generally visible in the Editor Settings menu. - + Accessing the settings is done by using the regular [Object] API, such as. - + settings.set(prop,value) - + settings.get(prop) - + list_of_settings = settings.get_property_list() </description> <methods> @@ -11481,9 +11488,9 @@ This approximation makes straight segments between each point, then subdivides t <description> Get the global settings path for the engine. Inside this path you can find some standard paths such as: - + settings/tmp - used for temporary storage of files - + settings/templates - where export templates are located </description> @@ -11559,7 +11566,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Commit a handle being edited (handles must have been prevously added by [method add_handles]). - + If the cancel parameter is true, an option to restore the edited value to the original is provided. @@ -11573,7 +11580,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Get the name of an edited handle (handles must have been previously added by [method add_handles]). - + Handles can be named for reference to the user when editing. </description> </method> @@ -11605,8 +11612,8 @@ This approximation makes straight segments between each point, then subdivides t <description> This function is used when the user drags a gizmo handle (previously added with [method add_handles]) - in screen coordinates. - + in screen coordinates. + The [Camera] is also provided so screen coordinates can be converted to raycasts. </description> @@ -11622,7 +11629,7 @@ This approximation makes straight segments between each point, then subdivides t Add lines to the gizmo (as sets of 2 points), with a given material. The lines are used for visualizing the gizmo. - + Call this function during [method redraw]. </description> </method> @@ -11636,7 +11643,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Add a mesh to the gizmo, this is used for visualization. - + Call this function during [method redraw]. </description> </method> @@ -11653,7 +11660,7 @@ This approximation makes straight segments between each point, then subdivides t Add collision triangles to the gizmo for picking. A [TriangleMesh] can be generated from a regular [Mesh] too. - + Call this function during [method redraw]. </description> </method> @@ -11664,7 +11671,7 @@ This approximation makes straight segments between each point, then subdivides t </argument> <description> Add an unscaled billboard for visualization. - + Call this function during [method redraw]. </description> </method> @@ -11678,10 +11685,10 @@ This approximation makes straight segments between each point, then subdivides t <description> Add a list of handles (points) which can be used to deform the object being edited. - + There are virtual functions which will be called upon editing of these handles. - + Call this function during [method redraw]. </description> </method> @@ -11691,7 +11698,7 @@ This approximation makes straight segments between each point, then subdivides t <description> Call this function once and upon creation of the gizmo, otherwise no other function will work. - + The argument is the node being edited by the gizmo. </description> </method> @@ -14449,7 +14456,7 @@ This approximation makes straight segments between each point, then subdivides t Hyper-text transfer protocol client. </brief_description> <description> - Hyper-text transfer protocol client. Supports SSL and SSL server certificate verification. + Hyper-text transfer protocol client. Supports SSL and SSL server certificate verification. Can be reused to connect to different hosts and make many requests. </description> <methods> @@ -14792,7 +14799,7 @@ Example: (content-length:12), (Content-Type:application/json; charset=UTF-8) A Node with the ability to send HTTP requests. </brief_description> <description> - A Node with the ability to send HTTP requests. Uses a [HTTPClient] internally, supports HTTPS. + A Node with the ability to send HTTP requests. Uses a [HTTPClient] internally, supports HTTPS. Can be used to make HTTP requests or download files via HTTP. </description> <methods> @@ -41413,7 +41420,7 @@ This method controls whether the position between two cached points is interpola <description> Helper to maange UndoRedo in the editor or custom tools. It works by storing calls to functions in both 'do' an 'undo' lists. - + Common behavior is to create an action, then add do/undo calls to functions or property changes, then commiting the action. </description> @@ -41537,8 +41544,8 @@ This method controls whether the position between two cached points is interpola <description> Get the version, each time a new action is commited, the version number of the UndoRedo is increased - automatically. - + automatically. + This is useful mostly to check if something changed from a saved version. </description> diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp index 79465638d1..8bd2fe3862 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp @@ -6497,7 +6497,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans if (!*e->additive_ptr) { additive=false; - *e->additive_ptr=true; + *e->additive_ptr=true; } else { additive=true; } @@ -6684,7 +6684,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans } rebind=true; } - + if (use_hw_skeleton_xform && (skeleton!=prev_skeleton||morph_values!=prev_morph_values)) { if (!prev_skeleton || !skeleton) rebind=true; //went from skeleton <-> no skeleton, needs rebind @@ -6718,7 +6718,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans DEBUG_TEST_ERROR("Setup geometry"); }; - if (i==0 || light!=prev_light || rebind) { + if (i==0 || light!=prev_light || rebind) { if (e->light!=0xFFFF) { _setup_light(e->light); @@ -6958,7 +6958,7 @@ void RasterizerGLES2::_process_glow_bloom() { _copy_screen_quad(); copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_COPY,false); - copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); + copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false); int passes = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_PASSES]; Vector2 psize(1.0/framebuffer.blur_size,1.0/framebuffer.blur_size); float pscale = current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_SCALE]; @@ -7427,7 +7427,7 @@ void RasterizerGLES2::end_scene() { _process_hdr(); } if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) { - _process_glow_bloom(); + _process_glow_bloom(); int glow_transfer_mode=current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE]; if (glow_transfer_mode==1) copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,true); @@ -8438,7 +8438,7 @@ void RasterizerGLES2::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R } -void RasterizerGLES2::canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) { +void RasterizerGLES2::canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) { Color m = p_modulate; m.a*=canvas_opacity; @@ -8446,52 +8446,57 @@ void RasterizerGLES2::canvas_draw_style_box(const Rect2& p_rect, RID p_texture,c Texture* texture=_bind_canvas_texture(p_texture); ERR_FAIL_COND(!texture); - /* CORNERS */ + Rect2 region = p_src_region; + if (region.size.width <= 0 ) + region.size.width = texture->width; + if (region.size.height <= 0) + region.size.height = texture->height; + /* CORNERS */ _draw_textured_quad( // top left Rect2( p_rect.pos, Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_TOP])), - Rect2( Point2(), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_TOP])), + Rect2( region.pos, Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_TOP])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // top right Rect2( Point2( p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_TOP])), - Rect2( Point2(texture->width-p_margin[MARGIN_RIGHT],0), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_TOP])), + Rect2( Point2(region.pos.x+region.size.width-p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_TOP])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // bottom left Rect2( Point2(p_rect.pos.x,p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_BOTTOM])), - Rect2( Point2(0,texture->height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_BOTTOM])), + Rect2( Point2(region.pos.x, region.pos.y+region.size.height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_BOTTOM])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // bottom right Rect2( Point2( p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_BOTTOM])), - Rect2( Point2(texture->width-p_margin[MARGIN_RIGHT],texture->height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_BOTTOM])), + Rect2( Point2(region.pos.x+region.size.width-p_margin[MARGIN_RIGHT], region.pos.y+region.size.height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_BOTTOM])), Size2( texture->width, texture->height ) ); Rect2 rect_center( p_rect.pos+Point2( p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2( p_rect.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], p_rect.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM] )); - Rect2 src_center( Point2( p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2( texture->width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], texture->height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM] )); + Rect2 src_center( Point2(region.pos.x+p_margin[MARGIN_LEFT], region.pos.y+p_margin[MARGIN_TOP]), Size2(region.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], region.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM] )); _draw_textured_quad( // top Rect2( Point2(rect_center.pos.x,p_rect.pos.y),Size2(rect_center.size.width,p_margin[MARGIN_TOP])), - Rect2( Point2(p_margin[MARGIN_LEFT],0), Size2(src_center.size.width,p_margin[MARGIN_TOP])), + Rect2( Point2(src_center.pos.x,region.pos.y), Size2(src_center.size.width,p_margin[MARGIN_TOP])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // bottom Rect2( Point2(rect_center.pos.x,rect_center.pos.y+rect_center.size.height),Size2(rect_center.size.width,p_margin[MARGIN_BOTTOM])), - Rect2( Point2(p_margin[MARGIN_LEFT],src_center.pos.y+src_center.size.height), Size2(src_center.size.width,p_margin[MARGIN_BOTTOM])), + Rect2( Point2(src_center.pos.x,src_center.pos.y+src_center.size.height), Size2(src_center.size.width,p_margin[MARGIN_BOTTOM])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // left Rect2( Point2(p_rect.pos.x,rect_center.pos.y),Size2(p_margin[MARGIN_LEFT],rect_center.size.height)), - Rect2( Point2(0,p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT],src_center.size.height)), + Rect2( Point2(region.pos.x,region.pos.y+p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT],src_center.size.height)), Size2( texture->width, texture->height ) ); _draw_textured_quad( // right Rect2( Point2(rect_center.pos.x+rect_center.size.width,rect_center.pos.y),Size2(p_margin[MARGIN_RIGHT],rect_center.size.height)), - Rect2( Point2(src_center.pos.x+src_center.size.width,p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT],src_center.size.height)), + Rect2( Point2(src_center.pos.x+src_center.size.width,region.pos.y+p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT],src_center.size.height)), Size2( texture->width, texture->height ) ); if (p_draw_center) { @@ -8569,7 +8574,7 @@ void RasterizerGLES2::canvas_draw_polygon(int p_vertex_count, const int* p_indic #else //WebGL specific impl. - glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer); + glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer); float *b = GlobalVertexBuffer; int ofs = 0; if(p_vertex_count > MAX_POLYGON_VERTICES){ @@ -9184,7 +9189,7 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem CanvasItem::CommandStyle* style = static_cast<CanvasItem::CommandStyle*>(c); if (use_normalmap) _canvas_normal_set_flip(Vector2(1,1)); - canvas_draw_style_box(style->rect,style->texture,style->margin,style->draw_center,style->color); + canvas_draw_style_box(style->rect,style->source,style->texture,style->margin,style->draw_center,style->color); } break; case CanvasItem::Command::TYPE_PRIMITIVE: { @@ -9430,7 +9435,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const draw_viewport_func(ci->vp_render->owner,ci->vp_render->udata,ci->vp_render->rect); } memdelete(ci->vp_render); - ci->vp_render=NULL; + ci->vp_render=NULL; canvas_last_material=NULL; canvas_use_modulate=p_modulate!=Color(1,1,1,1); canvas_modulate=p_modulate; @@ -11424,7 +11429,7 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo void RasterizerGLES2::restore_framebuffer() { glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer); - + } RasterizerGLES2::~RasterizerGLES2() { diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index 35efedc9c8..c9fc0c247d 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -1635,7 +1635,7 @@ public: virtual void canvas_end_rect(); virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width); virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate); - virtual void canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width); virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor); virtual void canvas_set_transform(const Matrix32& p_transform); diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp index d51f1a4ddc..072c53fb9f 100644 --- a/modules/gdscript/gd_compiler.cpp +++ b/modules/gdscript/gd_compiler.cpp @@ -1588,6 +1588,12 @@ Error GDCompiler::_parse_class(GDScript *p_script, GDScript *p_owner, const GDPa } + } else { + // without extends, implicitly extend Reference + int native_idx = GDScriptLanguage::get_singleton()->get_global_map()["Reference"]; + native = GDScriptLanguage::get_singleton()->get_global_array()[native_idx]; + ERR_FAIL_COND_V(native.is_null(), ERR_BUG); + p_script->native=native; } diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp index dcd0641f76..12fc36d8c1 100644 --- a/modules/gdscript/gd_script.cpp +++ b/modules/gdscript/gd_script.cpp @@ -145,11 +145,8 @@ Variant GDScript::_new(const Variant** p_args,int p_argcount,Variant::CallError& _baseptr=_baseptr->_base; } - if (_baseptr->native.ptr()) { - owner=_baseptr->native->instance(); - } else { - owner=memnew( Reference ); //by default, no base means use reference - } + ERR_FAIL_COND_V(_baseptr->native.is_null(), Variant()); + owner=_baseptr->native->instance(); Reference *r=owner->cast_to<Reference>(); if (r) { diff --git a/platform/iphone/rasterizer_iphone.cpp b/platform/iphone/rasterizer_iphone.cpp index f06f12547f..99e83343d0 100644 --- a/platform/iphone/rasterizer_iphone.cpp +++ b/platform/iphone/rasterizer_iphone.cpp @@ -2446,7 +2446,7 @@ void RasterizerIPhone::canvas_draw_rect(const Rect2& p_rect, bool p_region, cons } -void RasterizerIPhone::canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margin, bool p_draw_center) { +void RasterizerIPhone::canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margin, bool p_draw_center) { glColor4f(1, 1, 1, 1); @@ -2458,52 +2458,56 @@ void RasterizerIPhone::canvas_draw_style_box(const Rect2& p_rect, RID p_texture, glBindTexture( GL_TEXTURE_2D,texture->tex_id ); + Rect2 region = p_src_region; + if (region.size.width <= 0 ) + region.size.width = texture->width; + if (region.size.height <= 0) + region.size.height = texture->height; /* CORNERS */ - _draw_textured_quad( // top left Rect2( p_rect.pos, Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_TOP])), - Rect2( Point2(), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_TOP])), + Rect2( region.pos, Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_TOP])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // top right Rect2( Point2( p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_TOP])), - Rect2( Point2(texture->width-p_margin[MARGIN_RIGHT],0), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_TOP])), + Rect2( Point2(region.pos.x+region.size.width-p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_TOP])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // bottom left Rect2( Point2(p_rect.pos.x,p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_BOTTOM])), - Rect2( Point2(0,texture->height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_BOTTOM])), + Rect2( Point2(region.pos.x, region.pos.y+region.size.height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT],p_margin[MARGIN_BOTTOM])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // bottom right Rect2( Point2( p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_BOTTOM])), - Rect2( Point2(texture->width-p_margin[MARGIN_RIGHT],texture->height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_BOTTOM])), + Rect2( Point2(region.pos.x+region.size.width-p_margin[MARGIN_RIGHT], region.pos.y+region.size.height-p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT],p_margin[MARGIN_BOTTOM])), Size2( texture->width, texture->height ) ); Rect2 rect_center( p_rect.pos+Point2( p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2( p_rect.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], p_rect.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM] )); - Rect2 src_center( Point2( p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2( texture->width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], texture->height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM] )); + Rect2 src_center( Point2(region.pos.x+p_margin[MARGIN_LEFT], region.pos.y+p_margin[MARGIN_TOP]), Size2(region.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], region.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM] )); _draw_textured_quad( // top Rect2( Point2(rect_center.pos.x,p_rect.pos.y),Size2(rect_center.size.width,p_margin[MARGIN_TOP])), - Rect2( Point2(p_margin[MARGIN_LEFT],0), Size2(src_center.size.width,p_margin[MARGIN_TOP])), + Rect2( Point2(src_center.pos.x,region.pos.y), Size2(src_center.size.width,p_margin[MARGIN_TOP])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // bottom Rect2( Point2(rect_center.pos.x,rect_center.pos.y+rect_center.size.height),Size2(rect_center.size.width,p_margin[MARGIN_BOTTOM])), - Rect2( Point2(p_margin[MARGIN_LEFT],src_center.pos.y+src_center.size.height), Size2(src_center.size.width,p_margin[MARGIN_BOTTOM])), + Rect2( Point2(src_center.pos.x,src_center.pos.y+src_center.size.height), Size2(src_center.size.width,p_margin[MARGIN_BOTTOM])), Size2( texture->width, texture->height ) ); _draw_textured_quad( // left Rect2( Point2(p_rect.pos.x,rect_center.pos.y),Size2(p_margin[MARGIN_LEFT],rect_center.size.height)), - Rect2( Point2(0,p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT],src_center.size.height)), + Rect2( Point2(region.pos.x,region.pos.y+p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT],src_center.size.height)), Size2( texture->width, texture->height ) ); _draw_textured_quad( // right Rect2( Point2(rect_center.pos.x+rect_center.size.width,rect_center.pos.y),Size2(p_margin[MARGIN_RIGHT],rect_center.size.height)), - Rect2( Point2(src_center.pos.x+src_center.size.width,p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT],src_center.size.height)), + Rect2( Point2(src_center.pos.x+src_center.size.width,region.pos.y+p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT],src_center.size.height)), Size2( texture->width, texture->height ) ); if (p_draw_center) { diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index c99d3aa0f5..bd56369746 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -770,7 +770,7 @@ Size2 Control::get_minimum_size() const { Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { + if (p_type==StringName() || p_type=="") { const Ref<Texture>* tex = data.icon_override.getptr(p_name); if (tex) @@ -800,7 +800,7 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type } Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { + if (p_type==StringName() || p_type=="") { const Ref<Shader>* sdr = data.shader_override.getptr(p_name); if (sdr) @@ -830,7 +830,7 @@ Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_typ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { + if (p_type==StringName() || p_type=="") { const Ref<StyleBox>* style = data.style_override.getptr(p_name); if (style) return *style; @@ -858,7 +858,7 @@ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p } Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { + if (p_type==StringName() || p_type=="") { const Ref<Font>* font = data.font_override.getptr(p_name); if (font) return *font; @@ -889,7 +889,7 @@ Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) c } Color Control::get_color(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { + if (p_type==StringName() || p_type=="") { const Color* color = data.color_override.getptr(p_name); if (color) return *color; @@ -918,7 +918,7 @@ Color Control::get_color(const StringName& p_name,const StringName& p_type) cons int Control::get_constant(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { + if (p_type==StringName() || p_type=="") { const int* constant = data.constant_override.getptr(p_name); if (constant) return *constant; @@ -946,12 +946,64 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con } +bool Control::has_icon_override(const StringName& p_name) const { + + const Ref<Texture>* tex = data.icon_override.getptr(p_name); + if (tex) + return true; + else + return false; +} + +bool Control::has_shader_override(const StringName &p_name) const { + + const Ref<Shader>* sdr = data.shader_override.getptr(p_name); + if (sdr) + return true; + else + return false; +} + +bool Control::has_stylebox_override(const StringName& p_name) const { + + const Ref<StyleBox>* style = data.style_override.getptr(p_name); + if (style) + return true; + else + return false; +} + +bool Control::has_font_override(const StringName& p_name) const { + + const Ref<Font>* font = data.font_override.getptr(p_name); + if (font) + return true; + else + return false; +} + +bool Control::has_color_override(const StringName& p_name) const { + + const Color* color = data.color_override.getptr(p_name); + if (color) + return true; + else + return false; +} + +bool Control::has_constant_override(const StringName& p_name) const { + + const int* constant = data.constant_override.getptr(p_name); + if (constant) + return true; + else + return false; +} bool Control::has_icon(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { - const Ref<Texture>* tex = data.icon_override.getptr(p_name); - if (tex) + if (p_type==StringName() || p_type=="") { + if (has_icon_override(p_name) == true) return true; } @@ -977,11 +1029,10 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const } -bool Control::has_shader(const StringName &p_name, const StringName &p_type) const -{ - if (p_type==StringName()) { - const Ref<Shader>* sdr = data.shader_override.getptr(p_name); - if (sdr) +bool Control::has_shader(const StringName &p_name, const StringName &p_type) const { + + if (p_type==StringName() || p_type=="") { + if (has_shader_override(p_name)==true) return true; } @@ -1008,10 +1059,8 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con } bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { - const Ref<StyleBox>* style = data.style_override.getptr(p_name); - - if (style) + if (p_type==StringName() || p_type=="") { + if (has_stylebox_override(p_name)==true) return true; } @@ -1038,9 +1087,8 @@ bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) co } bool Control::has_font(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { - const Ref<Font>* font = data.font_override.getptr(p_name); - if (font) + if (p_type==StringName() || p_type=="") { + if (has_font_override(p_name)==true) return true; } @@ -1066,11 +1114,11 @@ bool Control::has_font(const StringName& p_name,const StringName& p_type) const return Theme::get_default()->has_font( p_name, type ); } -bool Control::has_color(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { - const Color* color = data.color_override.getptr(p_name); - if (color) +bool Control::has_color(const StringName& p_name, const StringName& p_type) const { + + if (p_type==StringName() || p_type=="") { + if (has_color_override(p_name)==true) return true; } @@ -1098,10 +1146,8 @@ bool Control::has_color(const StringName& p_name,const StringName& p_type) const bool Control::has_constant(const StringName& p_name,const StringName& p_type) const { - if (p_type==StringName()) { - - const int* constant = data.constant_override.getptr(p_name); - if (constant) + if (p_type==StringName() || p_type=="") { + if (has_constant_override(p_name) == true) return true; } @@ -2297,6 +2343,17 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_color","name","type"),&Control::get_color,DEFVAL("")); ObjectTypeDB::bind_method(_MD("get_constant","name","type"),&Control::get_constant,DEFVAL("")); + ObjectTypeDB::bind_method(_MD("has_icon_override", "name"), &Control::has_icon_override); + ObjectTypeDB::bind_method(_MD("has_stylebox_override", "name"), &Control::has_stylebox_override); + ObjectTypeDB::bind_method(_MD("has_font_override", "name"), &Control::has_font_override); + ObjectTypeDB::bind_method(_MD("has_color_override", "name"), &Control::has_color_override); + ObjectTypeDB::bind_method(_MD("has_constant_override", "name"), &Control::has_constant_override); + + ObjectTypeDB::bind_method(_MD("has_icon", "name", "type"), &Control::has_icon, DEFVAL("")); + ObjectTypeDB::bind_method(_MD("has_stylebox", "name", "type"), &Control::has_stylebox, DEFVAL("")); + ObjectTypeDB::bind_method(_MD("has_font", "name", "type"), &Control::has_font, DEFVAL("")); + ObjectTypeDB::bind_method(_MD("has_color", "name", "type"), &Control::has_color, DEFVAL("")); + ObjectTypeDB::bind_method(_MD("has_constant", "name", "type"), &Control::has_constant, DEFVAL("")); ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control); @@ -2326,6 +2383,7 @@ void Control::_bind_methods() { ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"),&Control::warp_mouse); + ObjectTypeDB::bind_method(_MD("minimum_size_changed"), &Control::minimum_size_changed); BIND_VMETHOD(MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event"))); BIND_VMETHOD(MethodInfo(Variant::VECTOR2,"get_minimum_size")); diff --git a/scene/gui/control.h b/scene/gui/control.h index d77ba27f60..59704ae29b 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -341,6 +341,13 @@ public: Color get_color(const StringName& p_name,const StringName& p_type=StringName()) const; int get_constant(const StringName& p_name,const StringName& p_type=StringName()) const; + bool has_icon_override(const StringName& p_name) const; + bool has_shader_override(const StringName& p_name) const; + bool has_stylebox_override(const StringName& p_name) const; + bool has_font_override(const StringName& p_name) const; + bool has_color_override(const StringName& p_name) const; + bool has_constant_override(const StringName& p_name) const; + bool has_icon(const StringName& p_name,const StringName& p_type=StringName()) const; bool has_shader(const StringName& p_name,const StringName& p_type=StringName()) const; bool has_stylebox(const StringName& p_name,const StringName& p_type=StringName()) const; diff --git a/scene/gui/patch_9_frame.cpp b/scene/gui/patch_9_frame.cpp index b6e261714c..3ecee7328b 100644 --- a/scene/gui/patch_9_frame.cpp +++ b/scene/gui/patch_9_frame.cpp @@ -9,10 +9,9 @@ void Patch9Frame::_notification(int p_what) { if (texture.is_null()) return; - Size2 s=get_size(); RID ci = get_canvas_item(); - VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate); + VS::get_singleton()->canvas_item_add_style_box(ci,Rect2(Point2(),s),region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center,modulate); // draw_texture_rect(texture,Rect2(Point2(),s),false,modulate); /* @@ -47,12 +46,15 @@ void Patch9Frame::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_modulate"), & Patch9Frame::get_modulate ); ObjectTypeDB::bind_method(_MD("set_patch_margin","margin","value"), & Patch9Frame::set_patch_margin ); ObjectTypeDB::bind_method(_MD("get_patch_margin","margin"), & Patch9Frame::get_patch_margin ); + ObjectTypeDB::bind_method(_MD("set_region_rect","rect"),&Patch9Frame::set_region_rect); + ObjectTypeDB::bind_method(_MD("get_region_rect"),&Patch9Frame::get_region_rect); ObjectTypeDB::bind_method(_MD("set_draw_center","draw_center"), & Patch9Frame::set_draw_center ); ObjectTypeDB::bind_method(_MD("get_draw_center"), & Patch9Frame::get_draw_center ); ADD_PROPERTYNZ( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), _SCS("set_texture"),_SCS("get_texture") ); ADD_PROPERTYNO( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate") ); ADD_PROPERTYNO( PropertyInfo( Variant::BOOL, "draw_center"), _SCS("set_draw_center"),_SCS("get_draw_center") ); + ADD_PROPERTYNZ( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/left",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_LEFT ); ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/top",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_TOP ); ADD_PROPERTYINZ( PropertyInfo( Variant::INT, "patch_margin/right",PROPERTY_HINT_RANGE,"0,16384,1"), _SCS("set_patch_margin"),_SCS("get_patch_margin"),MARGIN_RIGHT ); @@ -93,6 +95,20 @@ void Patch9Frame::set_patch_margin(Margin p_margin,int p_size) { margin[p_margin]=p_size; update(); minimum_size_changed(); + switch (p_margin) { + case MARGIN_LEFT: + _change_notify("patch_margin/left"); + break; + case MARGIN_TOP: + _change_notify("patch_margin/top"); + break; + case MARGIN_RIGHT: + _change_notify("patch_margin/right"); + break; + case MARGIN_BOTTOM: + _change_notify("patch_margin/bottom"); + break; + } } int Patch9Frame::get_patch_margin(Margin p_margin) const{ @@ -101,6 +117,22 @@ int Patch9Frame::get_patch_margin(Margin p_margin) const{ return margin[p_margin]; } +void Patch9Frame::set_region_rect(const Rect2& p_region_rect) { + + if (region_rect==p_region_rect) + return; + + region_rect=p_region_rect; + + item_rect_changed(); + _change_notify("region_rect"); +} + +Rect2 Patch9Frame::get_region_rect() const { + + return region_rect; +} + void Patch9Frame::set_draw_center(bool p_draw) { draw_center=p_draw; @@ -128,5 +160,3 @@ Patch9Frame::Patch9Frame() { Patch9Frame::~Patch9Frame() { } - - diff --git a/scene/gui/patch_9_frame.h b/scene/gui/patch_9_frame.h index 562a5b1d77..52e2324c3d 100644 --- a/scene/gui/patch_9_frame.h +++ b/scene/gui/patch_9_frame.h @@ -11,6 +11,7 @@ class Patch9Frame : public Control { bool draw_center; int margin[4]; + Rect2 region_rect; Color modulate; Ref<Texture> texture; protected: @@ -30,6 +31,9 @@ public: void set_patch_margin(Margin p_margin,int p_size); int get_patch_margin(Margin p_margin) const; + void set_region_rect(const Rect2& p_region_rect); + Rect2 get_region_rect() const; + void set_draw_center(bool p_enable); bool get_draw_center() const; diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h index b245ea1542..e75a2aa332 100644 --- a/scene/resources/bit_mask.h +++ b/scene/resources/bit_mask.h @@ -36,6 +36,8 @@ class BitMap : public Resource { OBJ_TYPE(BitMap,Resource); + OBJ_SAVE_TYPE(BitMap); + RES_BASE_EXTENSION("pbm"); Vector<uint8_t> bitmask; int width; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 75e38f9701..a61ffe8e97 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -138,7 +138,7 @@ void StyleBoxTexture::draw(RID p_canvas_item,const Rect2& p_rect) const { r.pos.y-=expand_margin[MARGIN_TOP]; r.size.x+=expand_margin[MARGIN_LEFT]+expand_margin[MARGIN_RIGHT]; r.size.y+=expand_margin[MARGIN_TOP]+expand_margin[MARGIN_BOTTOM]; - VisualServer::get_singleton()->canvas_item_add_style_box( p_canvas_item,r,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center); + VisualServer::get_singleton()->canvas_item_add_style_box( p_canvas_item,r,region_rect,texture->get_rid(),Vector2(margin[MARGIN_LEFT],margin[MARGIN_TOP]),Vector2(margin[MARGIN_RIGHT],margin[MARGIN_BOTTOM]),draw_center); } void StyleBoxTexture::set_draw_center(bool p_draw) { @@ -175,6 +175,20 @@ float StyleBoxTexture::get_expand_margin_size(Margin p_expand_margin) const { return expand_margin[p_expand_margin]; } +void StyleBoxTexture::set_region_rect(const Rect2& p_region_rect) { + + if (region_rect==p_region_rect) + return; + + region_rect=p_region_rect; + emit_changed(); +} + +Rect2 StyleBoxTexture::get_region_rect() const { + + return region_rect; +} + void StyleBoxTexture::_bind_methods() { @@ -187,10 +201,14 @@ void StyleBoxTexture::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_expand_margin_size","margin","size"),&StyleBoxTexture::set_expand_margin_size); ObjectTypeDB::bind_method(_MD("get_expand_margin_size","margin"),&StyleBoxTexture::get_expand_margin_size); + ObjectTypeDB::bind_method(_MD("set_region_rect","region"),&StyleBoxTexture::set_region_rect); + ObjectTypeDB::bind_method(_MD("get_region_rect"),&StyleBoxTexture::get_region_rect); + ObjectTypeDB::bind_method(_MD("set_draw_center","enable"),&StyleBoxTexture::set_draw_center); ObjectTypeDB::bind_method(_MD("get_draw_center"),&StyleBoxTexture::get_draw_center); ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture" ), _SCS("set_texture"),_SCS("get_texture") ); + ADD_PROPERTYNZ( PropertyInfo( Variant::RECT2, "region_rect"), _SCS("set_region_rect"),_SCS("get_region_rect")); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "margin/left", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_margin_size"),_SCS("get_margin_size"), MARGIN_LEFT ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "margin/right", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_margin_size"),_SCS("get_margin_size"), MARGIN_RIGHT ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "margin/top", PROPERTY_HINT_RANGE,"0,2048,1" ), _SCS("set_margin_size"),_SCS("get_margin_size"), MARGIN_TOP); @@ -505,4 +523,3 @@ StyleBoxImageMask::StyleBoxImageMask() { } expand=true; } - diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index 02d79bc2ac..98aaee754b 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -81,6 +81,7 @@ class StyleBoxTexture : public StyleBox { float expand_margin[4]; float margin[4]; + Rect2 region_rect; Ref<Texture> texture; bool draw_center; @@ -98,6 +99,9 @@ public: void set_margin_size(Margin p_margin,float p_size); float get_margin_size(Margin p_margin) const; + void set_region_rect(const Rect2& p_region_rect); + Rect2 get_region_rect() const; + void set_texture(RES p_texture); RES get_texture() const; diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index cbb75129d0..149e9ec4f9 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -698,3 +698,64 @@ }\ } +#define FUNC8R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ + if (Thread::get_caller_ID()!=server_thread) {\ + m_r ret;\ + command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8, &ret);\ + SYNC_DEBUG\ + return ret;\ + } else {\ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + +#define FUNC8RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ + if (Thread::get_caller_ID()!=server_thread) {\ + m_r ret;\ + command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8, &ret);\ + SYNC_DEBUG\ + return ret;\ + } else {\ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + + +#define FUNC8S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + +#define FUNC8SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + + +#define FUNC8(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + +#define FUNC8C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index f1ad685879..50ec6792cc 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -702,6 +702,7 @@ public: struct CommandStyle : public Command { Rect2 rect; + Rect2 source; RID texture; float margin[4]; bool draw_center; @@ -944,12 +945,12 @@ public: virtual void canvas_disable_blending()=0; virtual void canvas_set_opacity(float p_opacity)=0; virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode)=0; - virtual void canvas_begin_rect(const Matrix32& p_transform)=0;; + virtual void canvas_begin_rect(const Matrix32& p_transform)=0; virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect)=0; virtual void canvas_end_rect()=0; virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width)=0; virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate)=0; - virtual void canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; + virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width)=0; virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor)=0; virtual void canvas_set_transform(const Matrix32& p_transform)=0; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 3b12b503dd..0e71d224d5 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1627,7 +1627,7 @@ void RasterizerDummy::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R } -void RasterizerDummy::canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) { +void RasterizerDummy::canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) { } @@ -1959,4 +1959,3 @@ RasterizerDummy::RasterizerDummy() { RasterizerDummy::~RasterizerDummy() { }; - diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index 674c165966..ac320e55f9 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -708,7 +708,7 @@ public: virtual void canvas_end_rect(); virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width); virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate); - virtual void canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width); virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor); virtual void canvas_set_transform(const Matrix32& p_transform); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index b3721268bf..532247d94c 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -3745,7 +3745,7 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R } -void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture, const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); @@ -3755,6 +3755,7 @@ void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_re ERR_FAIL_COND(!style); style->texture=p_texture; style->rect=p_rect; + style->source=p_source; style->draw_center=p_draw_center; style->color=p_modulate; style->margin[MARGIN_LEFT]=p_topleft.x; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 39ea2f55e6..dcaac6e8d2 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -1171,7 +1171,7 @@ public: virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color); virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); - virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0); virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID()); virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID(), int p_count=-1); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index 80cf43d572..a97b232c03 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -607,7 +607,7 @@ public: FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& ); FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool ); FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool ); - FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& ); + FUNC8(canvas_item_add_style_box,RID, const Rect2& , const Rect2&, RID ,const Vector2& ,const Vector2&, bool ,const Color& ); FUNC6(canvas_item_add_primitive,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ,float ); FUNC5(canvas_item_add_polygon,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ); FUNC7(canvas_item_add_triangle_array,RID, const Vector<int>& , const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID , int ); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 5ac0e5b5d5..570a5a6ee4 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -705,10 +705,10 @@ void VisualServer::_bind_methods() { } -void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate) { +void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate) { ERR_FAIL_COND(p_margins.size()!=4); - canvas_item_add_style_box(p_item, p_rect, p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate); + canvas_item_add_style_box(p_item,p_rect,p_source,p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate); } void VisualServer::_camera_set_orthogonal(RID p_camera,float p_size,float p_z_near,float p_z_far) { @@ -822,5 +822,3 @@ VisualServer::~VisualServer() { singleton=NULL; } - - diff --git a/servers/visual_server.h b/servers/visual_server.h index f32e976b57..f330a6faee 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -52,7 +52,7 @@ class VisualServer : public Object { void _camera_set_orthogonal(RID p_camera,float p_size,float p_z_near,float p_z_far); void _viewport_set_rect(RID p_viewport,const Rect2& p_rect); Rect2 _viewport_get_rect(RID p_viewport) const; - void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1)); + void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1)); protected: RID _make_test_cube(); void _free_internal_rids(); @@ -1025,7 +1025,7 @@ public: virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; - virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; + virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0)=0; virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID())=0; virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID(), int p_count=-1)=0; diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp index 16614b5d2d..01a6e3514c 100644 --- a/tools/editor/editor_node.cpp +++ b/tools/editor/editor_node.cpp @@ -59,7 +59,7 @@ // plugins #include "plugins/sprite_frames_editor_plugin.h" -#include "plugins/sprite_region_editor_plugin.h" +#include "plugins/texture_region_editor_plugin.h" #include "plugins/canvas_item_editor_plugin.h" #include "addon_editor_plugin.h" #include "plugins/spatial_editor_plugin.h" @@ -106,6 +106,7 @@ #include "tools/editor/io_plugins/editor_font_import_plugin.h" #include "tools/editor/io_plugins/editor_sample_import_plugin.h" #include "tools/editor/io_plugins/editor_translation_import_plugin.h" +#include "tools/editor/io_plugins/editor_bitmask_import_plugin.h" #include "tools/editor/io_plugins/editor_mesh_import_plugin.h" #include "tools/editor/io_plugins/editor_export_scene.h" @@ -5215,7 +5216,7 @@ void EditorNode::_bind_methods() { ADD_SIGNAL( MethodInfo("play_pressed") ); ADD_SIGNAL( MethodInfo("pause_pressed") ); ADD_SIGNAL( MethodInfo("stop_pressed") ); - ADD_SIGNAL( MethodInfo("request_help") ); + ADD_SIGNAL( MethodInfo("request_help") ); ADD_SIGNAL( MethodInfo("script_add_function_request",PropertyInfo(Variant::OBJECT,"obj"),PropertyInfo(Variant::STRING,"function"),PropertyInfo(Variant::STRING_ARRAY,"args")) ); ADD_SIGNAL( MethodInfo("resource_saved",PropertyInfo(Variant::OBJECT,"obj")) ); @@ -6365,6 +6366,8 @@ EditorNode::EditorNode() { editor_import_export->add_import_plugin( Ref<EditorFontImportPlugin>( memnew(EditorFontImportPlugin(this)))); editor_import_export->add_import_plugin( Ref<EditorSampleImportPlugin>( memnew(EditorSampleImportPlugin(this)))); editor_import_export->add_import_plugin( Ref<EditorTranslationImportPlugin>( memnew(EditorTranslationImportPlugin(this)))); + editor_import_export->add_import_plugin( Ref<EditorBitMaskImportPlugin>( memnew(EditorBitMaskImportPlugin(this)))); + editor_import_export->add_export_plugin( Ref<EditorTextureExportPlugin>( memnew(EditorTextureExportPlugin))); editor_import_export->add_export_plugin( Ref<EditorSampleExportPlugin>( memnew(EditorSampleExportPlugin))); @@ -6404,7 +6407,7 @@ EditorNode::EditorNode() { add_editor_plugin( memnew( TileSetEditorPlugin(this) ) ); add_editor_plugin( memnew( TileMapEditorPlugin(this) ) ); add_editor_plugin( memnew( SpriteFramesEditorPlugin(this) ) ); - add_editor_plugin( memnew( SpriteRegionEditorPlugin(this) ) ); + add_editor_plugin( memnew( TextureRegionEditorPlugin(this) ) ); add_editor_plugin( memnew( Particles2DEditorPlugin(this) ) ); add_editor_plugin( memnew( Path2DEditorPlugin(this) ) ); add_editor_plugin( memnew( PathEditorPlugin(this) ) ); @@ -6636,6 +6639,3 @@ EditorPluginList::EditorPluginList() { EditorPluginList::~EditorPluginList() { } - - - diff --git a/tools/editor/io_plugins/editor_bitmask_import_plugin.cpp b/tools/editor/io_plugins/editor_bitmask_import_plugin.cpp new file mode 100644 index 0000000000..dca7d011ff --- /dev/null +++ b/tools/editor/io_plugins/editor_bitmask_import_plugin.cpp @@ -0,0 +1,357 @@ +#include "editor_bitmask_import_plugin.h" +#include "io/image_loader.h" +#include "tools/editor/editor_file_dialog.h" +#include "tools/editor/editor_dir_dialog.h" +#include "tools/editor/editor_node.h" +#include "tools/editor/property_editor.h" +#include "io/resource_saver.h" +#include "os/file_access.h" +#include "io/marshalls.h" +#include "tools/editor/editor_settings.h" + +class _EditorBitMaskImportOptions : public Object { + + OBJ_TYPE(_EditorBitMaskImportOptions, Object); +public: + + bool _set(const StringName& p_name, const Variant& p_value) { + + return false; + } + + bool _get(const StringName& p_name, Variant &r_ret) const{ + + return false; + } + + void _get_property_list(List<PropertyInfo> *p_list) const{ + + } + + static void _bind_methods() { + + ADD_SIGNAL(MethodInfo("changed")); + } + + + _EditorBitMaskImportOptions() { + + } + +}; + +class EditorBitMaskImportDialog : public ConfirmationDialog { + + OBJ_TYPE(EditorBitMaskImportDialog, ConfirmationDialog); + + EditorBitMaskImportPlugin *plugin; + + LineEdit *import_path; + LineEdit *save_path; + EditorFileDialog *file_select; + EditorDirDialog *save_select; + ConfirmationDialog *error_dialog; + PropertyEditor *option_editor; + +public: + + void _choose_files(const Vector<String>& p_path) { + + String files; + for (int i = 0; i<p_path.size(); i++) { + + if (i>0) + files += ","; + files += p_path[i]; + } + + import_path->set_text(files); + + } + void _choose_save_dir(const String& p_path) { + + save_path->set_text(p_path); + } + + void _browse() { + + file_select->popup_centered_ratio(); + } + + void _browse_target() { + + save_select->popup_centered_ratio(); + + } + + + void popup_import(const String& p_path) { + + popup_centered(Size2(400, 100)*EDSCALE); + if (p_path != "") { + + Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_path); + ERR_FAIL_COND(!rimd.is_valid()); + + save_path->set_text(p_path.get_base_dir()); + + String src = ""; + for (int i = 0; i<rimd->get_source_count(); i++) { + if (i>0) + src += ","; + src += EditorImportPlugin::expand_source_path(rimd->get_source_path(i)); + } + import_path->set_text(src); + } + } + + + void _import() { + + Vector<String> bitmasks = import_path->get_text().split(","); + + if (bitmasks.size() == 0) { + error_dialog->set_text(TTR("No bit masks to import!")); + error_dialog->popup_centered(Size2(200, 100)*EDSCALE); + } + + if (save_path->get_text().strip_edges() == "") { + error_dialog->set_text(TTR("Target path is empty.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!save_path->get_text().begins_with("res://")) { + error_dialog->set_text(TTR("Target path must be a complete resource path.")); + error_dialog->popup_centered_minsize(); + return; + } + + if (!DirAccess::exists(save_path->get_text())) { + error_dialog->set_text(TTR("Target path must exist.")); + error_dialog->popup_centered_minsize(); + return; + } + + for (int i = 0; i<bitmasks.size(); i++) { + + Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata); + + imd->add_source(EditorImportPlugin::validate_source_path(bitmasks[i])); + + String dst = save_path->get_text(); + if (dst == "") { + error_dialog->set_text(TTR("Save path is empty!")); + error_dialog->popup_centered(Size2(200, 100)*EDSCALE); + } + + dst = dst.plus_file(bitmasks[i].get_file().basename() + ".pbm"); + + Error err = plugin->import(dst, imd); + } + + hide(); + + } + + + void _notification(int p_what) { + + } + + static void _bind_methods() { + + + ObjectTypeDB::bind_method("_choose_files", &EditorBitMaskImportDialog::_choose_files); + ObjectTypeDB::bind_method("_choose_save_dir", &EditorBitMaskImportDialog::_choose_save_dir); + ObjectTypeDB::bind_method("_import", &EditorBitMaskImportDialog::_import); + ObjectTypeDB::bind_method("_browse", &EditorBitMaskImportDialog::_browse); + ObjectTypeDB::bind_method("_browse_target", &EditorBitMaskImportDialog::_browse_target); + // ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) ); + } + + EditorBitMaskImportDialog(EditorBitMaskImportPlugin *p_plugin) { + + plugin = p_plugin; + + + set_title(TTR("Import BitMasks")); + + VBoxContainer *vbc = memnew(VBoxContainer); + add_child(vbc); + set_child_rect(vbc); + + + HBoxContainer *hbc = memnew(HBoxContainer); + vbc->add_margin_child(TTR("Source Texture(s):"), hbc); + + import_path = memnew(LineEdit); + import_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(import_path); + + Button * import_choose = memnew(Button); + import_choose->set_text(" .. "); + hbc->add_child(import_choose); + + import_choose->connect("pressed", this, "_browse"); + + hbc = memnew(HBoxContainer); + vbc->add_margin_child(TTR("Target Path:"), hbc); + + save_path = memnew(LineEdit); + save_path->set_h_size_flags(SIZE_EXPAND_FILL); + hbc->add_child(save_path); + + Button * save_choose = memnew(Button); + save_choose->set_text(" .. "); + hbc->add_child(save_choose); + + save_choose->connect("pressed", this, "_browse_target"); + + file_select = memnew(EditorFileDialog); + file_select->set_access(EditorFileDialog::ACCESS_FILESYSTEM); + add_child(file_select); + file_select->set_mode(EditorFileDialog::MODE_OPEN_FILES); + file_select->connect("files_selected", this, "_choose_files"); + + List<String> extensions; + ImageLoader::get_recognized_extensions(&extensions); + file_select->clear_filters(); + for (int i = 0; i<extensions.size(); i++) { + + file_select->add_filter("*." + extensions[i] + " ; " + extensions[i].to_upper()); + } + + save_select = memnew(EditorDirDialog); + add_child(save_select); + + // save_select->set_mode(EditorFileDialog::MODE_OPEN_DIR); + save_select->connect("dir_selected", this, "_choose_save_dir"); + + get_ok()->connect("pressed", this, "_import"); + get_ok()->set_text(TTR("Import")); + + + error_dialog = memnew(ConfirmationDialog); + add_child(error_dialog); + error_dialog->get_ok()->set_text(TTR("Accept")); + // error_dialog->get_cancel()->hide(); + + set_hide_on_ok(false); + } + + ~EditorBitMaskImportDialog() { + } + +}; + + +String EditorBitMaskImportPlugin::get_name() const { + + return "bitmask"; +} +String EditorBitMaskImportPlugin::get_visible_name() const{ + + return TTR("Bit Mask"); +} +void EditorBitMaskImportPlugin::import_dialog(const String& p_from){ + + dialog->popup_import(p_from); +} +Error EditorBitMaskImportPlugin::import(const String& p_path, const Ref<ResourceImportMetadata>& p_from){ + + ERR_FAIL_COND_V(p_from->get_source_count() != 1, ERR_INVALID_PARAMETER); + + Ref<ResourceImportMetadata> from = p_from; + + String src_path = EditorImportPlugin::expand_source_path(from->get_source_path(0)); + Ref<ImageTexture> it = ResourceLoader::load(src_path); + ERR_FAIL_COND_V(it.is_null(), ERR_CANT_OPEN); + + Ref<BitMap> target = memnew(BitMap); + target->create_from_image_alpha(it.ptr()->get_data()); + + from->set_source_md5(0, FileAccess::get_md5(src_path)); + from->set_editor(get_name()); + target->set_import_metadata(from); + + + Error err = ResourceSaver::save(p_path, target); + + return err; + +} + + +EditorBitMaskImportPlugin* EditorBitMaskImportPlugin::singleton = NULL; + + +void EditorBitMaskImportPlugin::import_from_drop(const Vector<String>& p_drop, const String &p_dest_path) { + + Vector<String> files; + + List<String> valid_extensions; + ImageLoader::get_recognized_extensions(&valid_extensions); + for(int i=0;i<p_drop.size();i++) { + + String extension=p_drop[i].extension().to_lower(); + + for (List<String>::Element *E=valid_extensions.front();E;E=E->next()) { + + if (E->get()==extension) { + files.push_back(p_drop[i]); + break; + } + } + } + + if (files.size()) { + import_dialog(); + dialog->_choose_files(files); + dialog->_choose_save_dir(p_dest_path); + } +} + +void EditorBitMaskImportPlugin::reimport_multiple_files(const Vector<String>& p_list) { + + if (p_list.size() == 0) + return; + + Vector<String> sources; + for (int i = 0; i<p_list.size(); i++) { + int idx; + EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(p_list[i], &idx); + if (efsd) { + for (int j = 0; j<efsd->get_source_count(idx); j++) { + String file = expand_source_path(efsd->get_source_file(idx, j)); + if (sources.find(file) == -1) { + sources.push_back(file); + } + + } + } + } + + if (sources.size()) { + + dialog->popup_import(p_list[0]); + dialog->_choose_files(sources); + dialog->_choose_save_dir(p_list[0].get_base_dir()); + } +} + +bool EditorBitMaskImportPlugin::can_reimport_multiple_files() const { + + return true; +} + +EditorBitMaskImportPlugin::EditorBitMaskImportPlugin(EditorNode* p_editor) { + + singleton = this; + dialog = memnew(EditorBitMaskImportDialog(this)); + p_editor->get_gui_base()->add_child(dialog); +} + +EditorBitMaskExportPlugin::EditorBitMaskExportPlugin() { + +} diff --git a/tools/editor/io_plugins/editor_bitmask_import_plugin.h b/tools/editor/io_plugins/editor_bitmask_import_plugin.h new file mode 100644 index 0000000000..d9ca33cd97 --- /dev/null +++ b/tools/editor/io_plugins/editor_bitmask_import_plugin.h @@ -0,0 +1,41 @@ +#ifndef EDITOR_BITMASK_IMPORT_PLUGIN_H +#define EDITOR_BITMASK_IMPORT_PLUGIN_H + +#include "tools/editor/editor_import_export.h" +#include "scene/resources/font.h" + +class EditorNode; +class EditorBitMaskImportDialog; + +class EditorBitMaskImportPlugin : public EditorImportPlugin { + + OBJ_TYPE(EditorBitMaskImportPlugin, EditorImportPlugin); + + EditorBitMaskImportDialog *dialog; +public: + + static EditorBitMaskImportPlugin *singleton; + + virtual String get_name() const; + virtual String get_visible_name() const; + virtual void import_dialog(const String& p_from = ""); + virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from); + void import_from_drop(const Vector<String>& p_drop, const String &p_dest_path); + virtual void reimport_multiple_files(const Vector<String>& p_list); + virtual bool can_reimport_multiple_files() const; + + + EditorBitMaskImportPlugin(EditorNode* p_editor); +}; + +class EditorBitMaskExportPlugin : public EditorExportPlugin { + + OBJ_TYPE(EditorBitMaskExportPlugin, EditorExportPlugin); + + +public: + + EditorBitMaskExportPlugin(); +}; + +#endif // EDITOR_SAMPLE_IMPORT_PLUGIN_H diff --git a/tools/editor/plugins/sprite_region_editor_plugin.cpp b/tools/editor/plugins/texture_region_editor_plugin.cpp index 802a12eedd..b69b0d7a9b 100644 --- a/tools/editor/plugins/sprite_region_editor_plugin.cpp +++ b/tools/editor/plugins/texture_region_editor_plugin.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* sprite_region_editor_plugin.cpp */ +/* texture_region_editor_plugin.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -29,14 +29,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "sprite_region_editor_plugin.h" +#include "texture_region_editor_plugin.h" #include "scene/gui/check_box.h" #include "os/input.h" #include "os/keyboard.h" -void SpriteRegionEditor::_region_draw() +void TextureRegionEditor::_region_draw() { - Ref<Texture> base_tex = node->get_texture(); + Ref<Texture> base_tex = NULL; + if(node_type == "Sprite" && node_sprite) + base_tex = node_sprite->get_texture(); + else if(node_type == "Patch9Frame" && node_patch9) + base_tex = node_patch9->get_texture(); + else if(node_type == "StyleBoxTexture" && obj_styleBox) + base_tex = obj_styleBox->get_texture(); if (base_tex.is_null()) return; @@ -87,7 +93,9 @@ void SpriteRegionEditor::_region_draw() mtx.basis_xform(rect.pos+rect.size), mtx.basis_xform(rect.pos+Vector2(0,rect.size.y)) }; - + Color color(0.9,0.5,0.5); + if(this->editing_region == REGION_PATCH_MARGIN) + color = Color(0.21, 0.79, 0.31); for(int i=0;i<4;i++) { int prev = (i+3)%4; @@ -96,7 +104,7 @@ void SpriteRegionEditor::_region_draw() Vector2 ofs = ((endpoints[i] - endpoints[prev]).normalized() + ((endpoints[i] - endpoints[next]).normalized())).normalized(); ofs*=1.4144*(select_handle->get_size().width/2); - edit_draw->draw_line(endpoints[i]-draw_ofs, endpoints[next]-draw_ofs, Color(0.9,0.5,0.5), 2); + edit_draw->draw_line(endpoints[i]-draw_ofs, endpoints[next]-draw_ofs, color , 2); edit_draw->draw_texture(select_handle,(endpoints[i]+ofs-(select_handle->get_size()/2)).floor()-draw_ofs); @@ -124,7 +132,7 @@ void SpriteRegionEditor::_region_draw() updating_scroll=false; } -void SpriteRegionEditor::_region_input(const InputEvent& p_input) +void TextureRegionEditor::_region_input(const InputEvent& p_input) { Matrix32 mtx; mtx.elements[2]=-draw_ofs; @@ -154,7 +162,12 @@ void SpriteRegionEditor::_region_input(const InputEvent& p_input) drag_from=mtx.affine_inverse().xform(Vector2(mb.x,mb.y)); drag_from=snap_point(drag_from); drag=true; - rect_prev=node->get_region_rect(); + if(node_type == "Sprite" && node_sprite ) + rect_prev=node_sprite->get_region_rect(); + else if(node_type == "Patch9Frame" && node_patch9) + rect_prev=node_patch9->get_region_rect(); + else if(node_type == "StyleBoxTexture" && obj_styleBox) + rect_prev=obj_styleBox->get_region_rect(); drag_index=-1; for(int i=0;i<8;i++) { @@ -172,14 +185,20 @@ void SpriteRegionEditor::_region_input(const InputEvent& p_input) } } else if (drag) { - - undo_redo->create_action(TTR("Set region_rect")); - undo_redo->add_do_method(node,"set_region_rect",node->get_region_rect()); - undo_redo->add_undo_method(node,"set_region_rect",rect_prev); - undo_redo->add_do_method(edit_draw,"update"); - undo_redo->add_undo_method(edit_draw,"update"); - undo_redo->commit_action(); - + if(editing_region == REGION_TEXTURE_REGION) { + undo_redo->create_action("Set region_rect"); + if(node_type == "Sprite" && node_sprite ){ + undo_redo->add_do_method(node_sprite ,"set_region_rect",node_sprite->get_region_rect()); + undo_redo->add_undo_method(node_sprite,"set_region_rect",rect_prev); + } + else if(node_type == "Patch9Frame" && node_patch9){ + undo_redo->add_do_method(node_patch9 ,"set_region_rect",node_patch9->get_region_rect()); + undo_redo->add_undo_method(node_patch9,"set_region_rect",rect_prev); + } + undo_redo->add_do_method(edit_draw,"update"); + undo_redo->add_undo_method(edit_draw,"update"); + undo_redo->commit_action(); + } drag=false; } @@ -187,7 +206,7 @@ void SpriteRegionEditor::_region_input(const InputEvent& p_input) if (drag) { drag=false; - node->set_region_rect(rect_prev); + apply_rect(rect_prev); rect=rect_prev; edit_draw->update(); } @@ -218,60 +237,60 @@ void SpriteRegionEditor::_region_input(const InputEvent& p_input) if (creating) { rect = Rect2(drag_from,Size2()); rect.expand_to(new_pos); - node->set_region_rect(rect); + apply_rect(rect); edit_draw->update(); return; } switch(drag_index) { case 0: { - Vector2 p=rect_prev.pos+rect_prev.size; - rect = Rect2(p,Size2()); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos+rect_prev.size; + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 1: { - Vector2 p=rect_prev.pos+Vector2(0,rect_prev.size.y); - rect = Rect2(p,Size2(rect_prev.size.x,0)); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos+Vector2(0,rect_prev.size.y); + rect = Rect2(p,Size2(rect_prev.size.x,0)); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 2: { - Vector2 p=rect_prev.pos+Vector2(0,rect_prev.size.y); - rect = Rect2(p,Size2()); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos+Vector2(0,rect_prev.size.y); + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 3: { - Vector2 p=rect_prev.pos; - rect = Rect2(p,Size2(0,rect_prev.size.y)); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos; + rect = Rect2(p,Size2(0,rect_prev.size.y)); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 4: { - Vector2 p=rect_prev.pos; - rect = Rect2(p,Size2()); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos; + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 5: { - Vector2 p=rect_prev.pos; - rect = Rect2(p,Size2(rect_prev.size.x,0)); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos; + rect = Rect2(p,Size2(rect_prev.size.x,0)); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 6: { - Vector2 p=rect_prev.pos+Vector2(rect_prev.size.x,0); - rect = Rect2(p,Size2()); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos+Vector2(rect_prev.size.x,0); + rect = Rect2(p,Size2()); + rect.expand_to(new_pos); + apply_rect(rect); + } break; case 7: { - Vector2 p=rect_prev.pos+Vector2(rect_prev.size.x,0); - rect = Rect2(p,Size2(0,rect_prev.size.y)); - rect.expand_to(new_pos); - node->set_region_rect(rect); - } break; + Vector2 p=rect_prev.pos+Vector2(rect_prev.size.x,0); + rect = Rect2(p,Size2(0,rect_prev.size.y)); + rect.expand_to(new_pos); + apply_rect(rect); + } break; } edit_draw->update(); @@ -280,7 +299,7 @@ void SpriteRegionEditor::_region_input(const InputEvent& p_input) } } -void SpriteRegionEditor::_scroll_changed(float) +void TextureRegionEditor::_scroll_changed(float) { if (updating_scroll) return; @@ -292,47 +311,73 @@ void SpriteRegionEditor::_scroll_changed(float) edit_draw->update(); } -void SpriteRegionEditor::_set_use_snap(bool p_use) +void TextureRegionEditor::_set_use_snap(bool p_use) { use_snap=p_use; } -void SpriteRegionEditor::_set_show_grid(bool p_show) +void TextureRegionEditor::_set_show_grid(bool p_show) { snap_show_grid=p_show; edit_draw->update(); } -void SpriteRegionEditor::_set_snap_off_x(float p_val) +void TextureRegionEditor::_set_snap_off_x(float p_val) { snap_offset.x=p_val; edit_draw->update(); } -void SpriteRegionEditor::_set_snap_off_y(float p_val) +void TextureRegionEditor::_set_snap_off_y(float p_val) { snap_offset.y=p_val; edit_draw->update(); } -void SpriteRegionEditor::_set_snap_step_x(float p_val) +void TextureRegionEditor::_set_snap_step_x(float p_val) { snap_step.x=p_val; edit_draw->update(); } -void SpriteRegionEditor::_set_snap_step_y(float p_val) +void TextureRegionEditor::_set_snap_step_y(float p_val) { snap_step.y=p_val; edit_draw->update(); } -void SpriteRegionEditor::_notification(int p_what) +void TextureRegionEditor::apply_rect(const Rect2& rect){ + + if(this->editing_region == REGION_TEXTURE_REGION) { + if(node_sprite) + node_sprite->set_region_rect(rect); + else if(node_patch9) + node_patch9->set_region_rect(rect); + else if(obj_styleBox) + obj_styleBox->set_region_rect(rect); + } + else if(this->editing_region == REGION_PATCH_MARGIN) { + if(node_patch9) { + node_patch9->set_patch_margin(MARGIN_LEFT, rect.pos.x - tex_region.pos.x); + node_patch9->set_patch_margin(MARGIN_RIGHT, tex_region.pos.x+tex_region.size.width-(rect.pos.x+rect.size.width)); + node_patch9->set_patch_margin(MARGIN_TOP, rect.pos.y - tex_region.pos.y); + node_patch9->set_patch_margin(MARGIN_BOTTOM, tex_region.pos.y+tex_region.size.height-(rect.pos.y+rect.size.height)); + } + else if(obj_styleBox) { + obj_styleBox->set_margin_size(MARGIN_LEFT, rect.pos.x - tex_region.pos.x); + obj_styleBox->set_margin_size(MARGIN_RIGHT, tex_region.pos.x+tex_region.size.width-(rect.pos.x+rect.size.width)); + obj_styleBox->set_margin_size(MARGIN_TOP, rect.pos.y - tex_region.pos.y); + obj_styleBox->set_margin_size(MARGIN_BOTTOM, tex_region.pos.y+tex_region.size.height-(rect.pos.y+rect.size.height)); + } + } +} + +void TextureRegionEditor::_notification(int p_what) { switch(p_what) { - - case NOTIFICATION_READY: { - edit_node->set_icon( get_icon("RegionEdit","EditorIcons")); + case NOTIFICATION_READY: { + region_button->set_icon( get_icon("RegionEdit","EditorIcons")); + margin_button->set_icon( get_icon("Patch9Frame", "EditorIcons")); b_snap_grid->set_icon( get_icon("Grid", "EditorIcons")); b_snap_enable->set_icon( get_icon("Snap", "EditorIcons")); icon_zoom->set_texture( get_icon("Zoom", "EditorIcons")); @@ -340,60 +385,129 @@ void SpriteRegionEditor::_notification(int p_what) } } -void SpriteRegionEditor::_node_removed(Node *p_node) +void TextureRegionEditor::_node_removed(Object *p_obj) { - if(p_node==node) { - node=NULL; + if(p_obj == node_sprite || p_obj == node_patch9 || p_obj == obj_styleBox) { + node_patch9 = NULL; + node_sprite = NULL; + obj_styleBox = NULL; hide(); } } -void SpriteRegionEditor::_bind_methods() +void TextureRegionEditor::_bind_methods() { - ObjectTypeDB::bind_method(_MD("_edit_node"),&SpriteRegionEditor::_edit_node); - ObjectTypeDB::bind_method(_MD("_region_draw"),&SpriteRegionEditor::_region_draw); - ObjectTypeDB::bind_method(_MD("_region_input"),&SpriteRegionEditor::_region_input); - ObjectTypeDB::bind_method(_MD("_scroll_changed"),&SpriteRegionEditor::_scroll_changed); - ObjectTypeDB::bind_method(_MD("_node_removed"),&SpriteRegionEditor::_node_removed); - ObjectTypeDB::bind_method(_MD("_set_use_snap"),&SpriteRegionEditor::_set_use_snap); - ObjectTypeDB::bind_method(_MD("_set_show_grid"),&SpriteRegionEditor::_set_show_grid); - ObjectTypeDB::bind_method(_MD("_set_snap_off_x"),&SpriteRegionEditor::_set_snap_off_x); - ObjectTypeDB::bind_method(_MD("_set_snap_off_y"),&SpriteRegionEditor::_set_snap_off_y); - ObjectTypeDB::bind_method(_MD("_set_snap_step_x"),&SpriteRegionEditor::_set_snap_step_x); - ObjectTypeDB::bind_method(_MD("_set_snap_step_y"),&SpriteRegionEditor::_set_snap_step_y); + ObjectTypeDB::bind_method(_MD("_edit_node"),&TextureRegionEditor::_edit_node); + ObjectTypeDB::bind_method(_MD("_edit_region"),&TextureRegionEditor::_edit_region); + ObjectTypeDB::bind_method(_MD("_edit_margin"),&TextureRegionEditor::_edit_margin); + ObjectTypeDB::bind_method(_MD("_region_draw"),&TextureRegionEditor::_region_draw); + ObjectTypeDB::bind_method(_MD("_region_input"),&TextureRegionEditor::_region_input); + ObjectTypeDB::bind_method(_MD("_scroll_changed"),&TextureRegionEditor::_scroll_changed); + ObjectTypeDB::bind_method(_MD("_node_removed"),&TextureRegionEditor::_node_removed); + ObjectTypeDB::bind_method(_MD("_set_use_snap"),&TextureRegionEditor::_set_use_snap); + ObjectTypeDB::bind_method(_MD("_set_show_grid"),&TextureRegionEditor::_set_show_grid); + ObjectTypeDB::bind_method(_MD("_set_snap_off_x"),&TextureRegionEditor::_set_snap_off_x); + ObjectTypeDB::bind_method(_MD("_set_snap_off_y"),&TextureRegionEditor::_set_snap_off_y); + ObjectTypeDB::bind_method(_MD("_set_snap_step_x"),&TextureRegionEditor::_set_snap_step_x); + ObjectTypeDB::bind_method(_MD("_set_snap_step_y"),&TextureRegionEditor::_set_snap_step_y); } -void SpriteRegionEditor::edit(Node *p_sprite) +void TextureRegionEditor::edit(Object *p_obj) { - if (p_sprite) { - node=p_sprite->cast_to<Sprite>(); - node->connect("exit_tree",this,"_node_removed",varray(p_sprite),CONNECT_ONESHOT); + if (p_obj) { + margin_button->hide(); + node_type = p_obj->get_type(); + if(node_type == "Sprite"){ + node_sprite = p_obj->cast_to<Sprite>(); + node_patch9 = NULL; + obj_styleBox = NULL; + } + else if(node_type == "Patch9Frame") { + node_patch9 = p_obj->cast_to<Patch9Frame>(); + node_sprite = NULL; + obj_styleBox = NULL; + margin_button->show(); + } + else if(node_type == "StyleBoxTexture") { + obj_styleBox = p_obj->cast_to<StyleBoxTexture>(); + node_sprite = NULL; + node_patch9 = NULL; + margin_button->show(); + } + p_obj->connect("exit_tree",this,"_node_removed",varray(p_obj),CONNECT_ONESHOT); } else { - if (node) - node->disconnect("exit_tree",this,"_node_removed"); - node=NULL; + if(node_sprite) + node_sprite->disconnect("exit_tree",this,"_node_removed"); + else if(node_patch9) + node_patch9->disconnect("exit_tree",this,"_node_removed"); + else if(obj_styleBox) + obj_styleBox->disconnect("exit_tree",this,"_node_removed"); + node_sprite = NULL; + node_patch9 = NULL; + obj_styleBox = NULL; } +} +void TextureRegionEditor::_edit_region() +{ + this->_edit_node(REGION_TEXTURE_REGION); + dlg_editor->set_title(TTR("Texture Region Editor")); } -void SpriteRegionEditor::_edit_node() + +void TextureRegionEditor::_edit_margin() { - if (node->get_texture().is_null()) { + this->_edit_node(REGION_PATCH_MARGIN); + dlg_editor->set_title(TTR("Scale Region Editor")); +} - error->set_text("No texture in this sprite.\nSet a texture to be able to edit Region."); +void TextureRegionEditor::_edit_node(int region) +{ + Ref<Texture> texture = NULL; + if(node_type == "Sprite" && node_sprite ) + texture = node_sprite->get_texture(); + else if(node_type == "Patch9Frame" && node_patch9 ) + texture = node_patch9->get_texture(); + else if(node_type == "StyleBoxTexture" && obj_styleBox) + texture = obj_styleBox->get_texture(); + + if (texture.is_null()) { + error->set_text(TTR("No texture in this node.\nSet a texture to be able to edit region.")); error->popup_centered_minsize(); return; } - rect=node->get_region_rect(); + if(node_type == "Sprite" && node_sprite ) + tex_region = node_sprite->get_region_rect(); + else if(node_type == "Patch9Frame" && node_patch9 ) + tex_region = node_patch9->get_region_rect(); + else if(node_type == "StyleBoxTexture" && obj_styleBox) + tex_region = obj_styleBox->get_region_rect(); + rect = tex_region; + + if(region == REGION_PATCH_MARGIN) { + if(node_patch9){ + Patch9Frame *node = node_patch9; + rect.pos += Point2(node->get_patch_margin(MARGIN_LEFT),node->get_patch_margin(MARGIN_TOP)); + rect.size -= Size2(node->get_patch_margin(MARGIN_RIGHT)+node->get_patch_margin(MARGIN_LEFT), node->get_patch_margin(MARGIN_BOTTOM)+node->get_patch_margin(MARGIN_TOP)); + } + else if(obj_styleBox) { + StyleBoxTexture * node = obj_styleBox; + rect.pos += Point2(node->get_margin_size(MARGIN_LEFT),node->get_margin_size(MARGIN_TOP)); + rect.size -= Size2(node->get_margin_size(MARGIN_RIGHT)+node->get_margin_size(MARGIN_LEFT), node->get_margin_size(MARGIN_BOTTOM)+node->get_margin_size(MARGIN_TOP)); + } + } + dlg_editor->popup_centered_ratio(0.85); dlg_editor->get_ok()->release_focus(); + + editing_region = region; } inline float _snap_scalar(float p_offset, float p_step, float p_target) { return p_step != 0 ? Math::stepify(p_target - p_offset, p_step) + p_offset : p_target; } -Vector2 SpriteRegionEditor::snap_point(Vector2 p_target) const { +Vector2 TextureRegionEditor::snap_point(Vector2 p_target) const { if (use_snap) { p_target.x = _snap_scalar(snap_offset.x, snap_step.x, p_target.x); p_target.y = _snap_scalar(snap_offset.y, snap_step.y, p_target.y); @@ -403,9 +517,10 @@ Vector2 SpriteRegionEditor::snap_point(Vector2 p_target) const { return p_target; } -SpriteRegionEditor::SpriteRegionEditor(EditorNode* p_editor) +TextureRegionEditor::TextureRegionEditor(EditorNode* p_editor) { - node=NULL; + node_sprite = NULL; + node_patch9 = NULL; editor=p_editor; undo_redo = editor->get_undo_redo(); @@ -415,14 +530,18 @@ SpriteRegionEditor::SpriteRegionEditor(EditorNode* p_editor) drag=false; add_child( memnew( VSeparator )); - edit_node = memnew( ToolButton ); - add_child(edit_node); - edit_node->set_tooltip(TTR("Sprite Region Editor")); - edit_node->connect("pressed",this,"_edit_node"); + region_button = memnew( ToolButton ); + add_child(region_button); + region_button->set_tooltip(TTR("Texture Region Editor")); + region_button->connect("pressed",this,"_edit_region"); + + margin_button = memnew( ToolButton ); + add_child(margin_button); + margin_button->set_tooltip(TTR("Scale Region Editor")); + margin_button->connect("pressed",this,"_edit_margin"); dlg_editor = memnew( AcceptDialog ); add_child(dlg_editor); - dlg_editor->set_title(TTR("Sprite Region Editor")); dlg_editor->set_self_opacity(0.9); VBoxContainer *main_vb = memnew( VBoxContainer ); @@ -535,17 +654,17 @@ SpriteRegionEditor::SpriteRegionEditor(EditorNode* p_editor) } -void SpriteRegionEditorPlugin::edit(Object *p_node) +void TextureRegionEditorPlugin::edit(Object *p_node) { - region_editor->edit(p_node->cast_to<Node>()); + region_editor->edit(p_node); } -bool SpriteRegionEditorPlugin::handles(Object *p_node) const +bool TextureRegionEditorPlugin::handles(Object *p_obj) const { - return p_node->is_type("Sprite"); + return p_obj->is_type("Sprite") || p_obj->is_type("Patch9Frame") || p_obj->is_type("StyleBoxTexture"); } -void SpriteRegionEditorPlugin::make_visible(bool p_visible) +void TextureRegionEditorPlugin::make_visible(bool p_visible) { if (p_visible) { region_editor->show(); @@ -556,7 +675,7 @@ void SpriteRegionEditorPlugin::make_visible(bool p_visible) } -Dictionary SpriteRegionEditorPlugin::get_state() const { +Dictionary TextureRegionEditorPlugin::get_state() const { Dictionary state; state["zoom"]=region_editor->zoom->get_val(); @@ -567,7 +686,7 @@ Dictionary SpriteRegionEditorPlugin::get_state() const { return state; } -void SpriteRegionEditorPlugin::set_state(const Dictionary& p_state){ +void TextureRegionEditorPlugin::set_state(const Dictionary& p_state){ Dictionary state=p_state; if (state.has("zoom")) { @@ -599,12 +718,11 @@ void SpriteRegionEditorPlugin::set_state(const Dictionary& p_state){ } } -SpriteRegionEditorPlugin::SpriteRegionEditorPlugin(EditorNode *p_node) +TextureRegionEditorPlugin::TextureRegionEditorPlugin(EditorNode *p_node) { editor = p_node; - region_editor= memnew ( SpriteRegionEditor(p_node) ); + region_editor= memnew ( TextureRegionEditor(p_node) ); CanvasItemEditor::get_singleton()->add_control_to_menu_panel(region_editor); region_editor->hide(); } - diff --git a/tools/editor/plugins/sprite_region_editor_plugin.h b/tools/editor/plugins/texture_region_editor_plugin.h index 47cb210863..951b11e1e6 100644 --- a/tools/editor/plugins/sprite_region_editor_plugin.h +++ b/tools/editor/plugins/texture_region_editor_plugin.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* sprite_region_editor_plugin.h */ +/* texture_region_editor_plugin.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -29,22 +29,27 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef SPRITE_REGION_EDITOR_PLUGIN_H -#define SPRITE_REGION_EDITOR_PLUGIN_H +#ifndef TEXTURE_REGION_EDITOR_PLUGIN_H +#define TEXTURE_REGION_EDITOR_PLUGIN_H #include "canvas_item_editor_plugin.h" #include "tools/editor/editor_plugin.h" #include "tools/editor/editor_node.h" #include "scene/2d/sprite.h" +#include "scene/gui/patch_9_frame.h" +#include "scene/resources/style_box.h" -class SpriteRegionEditor : public HBoxContainer { +class TextureRegionEditor : public HBoxContainer { - OBJ_TYPE(SpriteRegionEditor, HBoxContainer ); + OBJ_TYPE(TextureRegionEditor, HBoxContainer ); + enum RegionType { + REGION_TEXTURE_REGION, + REGION_PATCH_MARGIN + }; - friend class SpriteRegionEditorPlugin; - - ToolButton *edit_node; -// Button *use_region; + friend class TextureRegionEditorPlugin; + ToolButton *region_button; + ToolButton *margin_button; ToolButton *b_snap_enable; ToolButton *b_snap_grid; TextureFrame *icon_zoom; @@ -59,7 +64,6 @@ class SpriteRegionEditor : public HBoxContainer { VScrollBar *vscroll; HScrollBar *hscroll; - Sprite *node; EditorNode *editor; AcceptDialog *dlg_editor; UndoRedo* undo_redo; @@ -73,8 +77,17 @@ class SpriteRegionEditor : public HBoxContainer { Vector2 snap_offset; Vector2 snap_step; + + String node_type; + Patch9Frame *node_patch9; + Sprite *node_sprite; + StyleBoxTexture *obj_styleBox; + + int editing_region; Rect2 rect; Rect2 rect_prev; + Rect2 tex_region; + bool drag; bool creating; Vector2 drag_from; @@ -88,34 +101,34 @@ class SpriteRegionEditor : public HBoxContainer { void _set_snap_off_y(float p_val); void _set_snap_step_x(float p_val); void _set_snap_step_y(float p_val); - + void apply_rect(const Rect2& rect); protected: void _notification(int p_what); - void _node_removed(Node *p_node); + void _node_removed(Object *p_obj); static void _bind_methods(); Vector2 snap_point(Vector2 p_target) const; public: - void edit(); - void _edit_node(); + void _edit_node(int tex_region); + void _edit_region(); + void _edit_margin(); void _region_draw(); void _region_input(const InputEvent &p_input); void _scroll_changed(float); - void edit(Node *p_sprite); - SpriteRegionEditor(EditorNode* p_editor); + void edit(Object *p_obj); + TextureRegionEditor(EditorNode* p_editor); }; -class SpriteRegionEditorPlugin : public EditorPlugin +class TextureRegionEditorPlugin : public EditorPlugin { + OBJ_TYPE( TextureRegionEditorPlugin, EditorPlugin ); - OBJ_TYPE( SpriteRegionEditorPlugin, EditorPlugin ); - - SpriteRegionEditor *region_editor; + TextureRegionEditor *region_editor; EditorNode *editor; public: @@ -127,7 +140,7 @@ public: void set_state(const Dictionary &p_state); Dictionary get_state() const; - SpriteRegionEditorPlugin(EditorNode *p_node); + TextureRegionEditorPlugin(EditorNode *p_node); }; -#endif // SPRITE_REGION_EDITOR_PLUGIN_H +#endif // TEXTURE_REGION_EDITOR_PLUGIN_H diff --git a/tools/editor/project_settings.cpp b/tools/editor/project_settings.cpp index 86f1ae6f9f..6822e50b73 100644 --- a/tools/editor/project_settings.cpp +++ b/tools/editor/project_settings.cpp @@ -834,35 +834,104 @@ void ProjectSettings::_autoload_edited() { return; TreeItem *ti = autoload_list->get_edited(); - if (!ti || autoload_list->get_edited_column()!=2) + int column = autoload_list->get_edited_column(); + + if (!ti || (column != 0 && column != 2)) return; - updating_autoload=true; - bool checked=ti->is_checked(2); + if (column == 0) { + String name = ti->get_text(0); + String old_name = selected_autoload.substr(selected_autoload.find("/")+1,selected_autoload.length()); - String base="autoload/"+ti->get_text(0); + if (!name.is_valid_identifier()) { + ti->set_text(0,old_name); + message->set_text(TTR("Invalid name.")+"\n"+TTR("Valid characters:")+" a-z, A-Z, 0-9 or _"); + message->popup_centered(Size2(300,100)); + return; + } - String path = Globals::get_singleton()->get(base); - int order = Globals::get_singleton()->get_order(base); + if (ObjectTypeDB::type_exists(name)) { + ti->set_text(0,old_name); + message->set_text(TTR("Invalid name. Must not collide with an existing engine class name.")); + message->popup_centered(Size2(400,100)); + return; + } - if (path.begins_with("*")) - path=path.substr(1,path.length()); + for(int i=0;i<Variant::VARIANT_MAX;i++) { + if (Variant::get_type_name(Variant::Type(i))==name) { + ti->set_text(0,old_name); + message->set_text(TTR("Invalid name. Must not collide with an existing buit-in type name.")); + message->popup_centered(Size2(400,100)); + return; + } + } - if (checked) - path="*"+path; + for(int i=0;i<GlobalConstants::get_global_constant_count();i++) { + if (GlobalConstants::get_global_constant_name(i)==name) { + ti->set_text(0,old_name); + message->set_text(TTR("Invalid name. Must not collide with an existing global constant name.")); + message->popup_centered(Size2(400,100)); + return; + } + } - undo_redo->create_action(TTR("Toggle AutoLoad Globals")); - undo_redo->add_do_property(Globals::get_singleton(),base,path); - undo_redo->add_undo_property(Globals::get_singleton(),base,Globals::get_singleton()->get(base)); - undo_redo->add_do_method(Globals::get_singleton(),"set_order",base,order); // keep order, as config order matters for these - undo_redo->add_undo_method(Globals::get_singleton(),"set_order",base,order); - undo_redo->add_do_method(this,"_update_autoload"); - undo_redo->add_undo_method(this,"_update_autoload"); - undo_redo->add_do_method(this,"_settings_changed"); - undo_redo->add_undo_method(this,"_settings_changed"); - undo_redo->commit_action(); - updating_autoload=false; + if (Globals::get_singleton()->has("autoload/"+name)) { + ti->set_text(0,old_name); + message->set_text(vformat(TTR("Autoload '%s' already exists!"),name)); + message->popup_centered(Size2(300,100)); + return; + } + + updating_autoload = true; + + name = "autoload/"+name; + String path = Globals::get_singleton()->get(selected_autoload); + bool is_persisting = Globals::get_singleton()->is_persisting(selected_autoload); + int order = Globals::get_singleton()->get_order(selected_autoload); + + undo_redo->create_action(TTR("Rename Autoload")); + undo_redo->add_do_property(Globals::get_singleton(),name,path); + undo_redo->add_do_method(Globals::get_singleton(),"set_persisting",name,is_persisting); + undo_redo->add_do_method(Globals::get_singleton(),"set_order",name,order); + undo_redo->add_do_method(Globals::get_singleton(),"clear",selected_autoload); + undo_redo->add_undo_property(Globals::get_singleton(),selected_autoload,path); + undo_redo->add_undo_method(Globals::get_singleton(),"set_persisting",selected_autoload,is_persisting); + undo_redo->add_undo_method(Globals::get_singleton(),"set_order",selected_autoload,order); + undo_redo->add_undo_method(Globals::get_singleton(),"clear",name); + undo_redo->add_do_method(this,"_update_autoload"); + undo_redo->add_undo_method(this,"_update_autoload"); + undo_redo->add_do_method(this,"_settings_changed"); + undo_redo->add_undo_method(this,"_settings_changed"); + undo_redo->commit_action(); + + selected_autoload = name; + } else if (column == 2) { + updating_autoload = true; + bool checked = ti->is_checked(2); + String base = "autoload/"+ti->get_text(0); + String path = Globals::get_singleton()->get(base); + int order = Globals::get_singleton()->get_order(base); + + if (path.begins_with("*")) + path = path.substr(1,path.length()); + + if (checked) + path = "*" + path; + + undo_redo->create_action(TTR("Toggle AutoLoad Globals")); + undo_redo->add_do_property(Globals::get_singleton(),base,path); + undo_redo->add_undo_property(Globals::get_singleton(),base,Globals::get_singleton()->get(base)); + undo_redo->add_do_method(Globals::get_singleton(),"set_order",base,order); // keep order, as config order matters for these + undo_redo->add_undo_method(Globals::get_singleton(),"set_order",base,order); + undo_redo->add_do_method(this,"_update_autoload"); + undo_redo->add_undo_method(this,"_update_autoload"); + undo_redo->add_do_method(this,"_settings_changed"); + undo_redo->add_undo_method(this,"_settings_changed"); + undo_redo->commit_action(); + } + + updating_autoload = false; } void ProjectSettings::_autoload_add() { @@ -990,6 +1059,14 @@ void ProjectSettings::_autoload_delete(Object *p_item,int p_column, int p_button } +void ProjectSettings::_autoload_selected() { + TreeItem *ti = autoload_list->get_selected(); + + if (!ti) + return; + + selected_autoload = "autoload/"+ti->get_text(0); +} void ProjectSettings::_translation_delete(Object *p_item,int p_column, int p_button) { @@ -1348,6 +1425,7 @@ void ProjectSettings::_update_autoload() { } TreeItem *t = autoload_list->create_item(root); t->set_text(0,name); + t->set_editable(0,true); t->set_text(1,path); t->set_cell_mode(2,TreeItem::CELL_MODE_CHECK); t->set_editable(2,true); @@ -1436,6 +1514,7 @@ void ProjectSettings::_bind_methods() { ObjectTypeDB::bind_method(_MD("_update_autoload"),&ProjectSettings::_update_autoload); ObjectTypeDB::bind_method(_MD("_autoload_delete"),&ProjectSettings::_autoload_delete); ObjectTypeDB::bind_method(_MD("_autoload_edited"),&ProjectSettings::_autoload_edited); + ObjectTypeDB::bind_method(_MD("_autoload_selected"),&ProjectSettings::_autoload_selected); ObjectTypeDB::bind_method(_MD("_clear_search_box"),&ProjectSettings::_clear_search_box); ObjectTypeDB::bind_method(_MD("_toggle_search_bar"),&ProjectSettings::_toggle_search_bar); @@ -1838,6 +1917,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) { autoload_list->connect("button_pressed",this,"_autoload_delete"); autoload_list->connect("item_edited",this,"_autoload_edited"); + autoload_list->connect("cell_selected", this, "_autoload_selected"); updating_autoload=false; diff --git a/tools/editor/project_settings.h b/tools/editor/project_settings.h index 113cc49b7c..5108378ff7 100644 --- a/tools/editor/project_settings.h +++ b/tools/editor/project_settings.h @@ -91,6 +91,7 @@ class ProjectSettings : public AcceptDialog { Tree *autoload_list; + String selected_autoload; EditorFileDialog *autoload_file_open; LineEdit *autoload_add_name; LineEdit *autoload_add_path; @@ -104,6 +105,7 @@ class ProjectSettings : public AcceptDialog { void _autoload_edited(); void _autoload_file_open(); void _autoload_delete(Object *p_item,int p_column, int p_button); + void _autoload_selected(); bool updating_autoload; |