This commit is contained in:
Juan Linietsky 2015-12-08 17:48:03 -03:00
commit c650d4e19c
49 changed files with 1129 additions and 599 deletions

1
.gitignore vendored
View file

@ -15,6 +15,7 @@ core/method_bind.inc
core/method_bind_ext.inc
core/script_encryption_key.cpp
core/global_defaults.cpp
drivers/unix/os_unix_global_settings_path.cpp
tools/editor/register_exporters.cpp
tools/editor/doc_data_compressed.h
tools/editor/editor_icons.cpp

View file

@ -127,6 +127,7 @@ opts.Add("CXX", "Compiler");
opts.Add("CCFLAGS", "Custom flags for the C++ compiler");
opts.Add("CFLAGS", "Custom flags for the C compiler");
opts.Add("LINKFLAGS", "Custom flags for the linker");
opts.Add('unix_global_settings_path', 'unix-specific path to system-wide settings. Currently only used by templates.','')
opts.Add('disable_3d', 'Disable 3D nodes for smaller executable (yes/no)', "no")
opts.Add('disable_advanced_gui', 'Disable advance 3D gui nodes and behaviors (yes/no)', "no")
opts.Add('colored', 'Enable colored output for the compilation (yes/no)', 'no')

View file

@ -184,6 +184,7 @@ public:
virtual void set_low_processor_usage_mode(bool p_enabled);
virtual bool is_in_low_processor_usage_mode() const;
virtual String get_installed_templates_path() const { return ""; };
virtual String get_executable_path() const;
virtual Error execute(const String& p_path, const List<String>& p_arguments,bool p_blocking,ProcessID *r_child_id=NULL,String* r_pipe=NULL,int *r_exitcode=NULL)=0;
virtual Error kill(const ProcessID& p_pid)=0;

View file

@ -897,17 +897,8 @@ String String::num(double p_num,int p_decimals) {
}
char buf[256];
#if defined(__GNUC__)
#ifdef MINGW_ENABLED
//snprintf is inexplicably broken in mingw
//sprintf(buf,fmt,p_num);
_snprintf(buf,256,fmt,p_num);
#else
#if defined(__GNUC__) || defined(_MSC_VER)
snprintf(buf,256,fmt,p_num);
#endif
#elif defined(_MSC_VER)
_snprintf(buf,256,fmt,p_num);
#else
sprintf(buf,fmt,p_num);
#endif
@ -1178,10 +1169,7 @@ String String::num_scientific(double p_num) {
char buf[256];
#if defined(_MSC_VER) || defined(MINGW_ENABLED)
_snprintf(buf,256,"%lg",p_num);
#elif defined(__GNUC__)
#if defined(__GNUC__) || defined(_MSC_VER)
snprintf(buf,256,"%lg",p_num);
#else
sprintf(buf,"%.16lg",p_num);
@ -3096,7 +3084,11 @@ String String::http_escape() const {
res += ord;
} else {
char h_Val[3];
snprintf(h_Val, 3, "%.2X", ord);
#if defined(__GNUC__) || defined(_MSC_VER)
snprintf(h_Val, 3, "%.2X", ord);
#else
sprintf(h_Val, "%.2X", ord);
#endif
res += "%";
res += h_Val;
}

View file

@ -42,7 +42,7 @@
template<class T>
class Vector {
mutable void* _ptr;
mutable T* _ptr;
// internal helpers
@ -51,21 +51,21 @@ class Vector {
if (!_ptr)
return NULL;
return reinterpret_cast<SafeRefCount*>(_ptr);
return reinterpret_cast<SafeRefCount*>((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount));
}
_FORCE_INLINE_ int* _get_size() const {
if (!_ptr)
return NULL;
return reinterpret_cast<int*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount));
return reinterpret_cast<int*>((uint8_t*)_ptr-sizeof(int));
}
_FORCE_INLINE_ T* _get_data() const {
if (!_ptr)
return NULL;
return reinterpret_cast<T*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount)+sizeof(int));
return reinterpret_cast<T*>(_ptr);
}
@ -88,11 +88,11 @@ public:
_FORCE_INLINE_ void clear() { resize(0); }
_FORCE_INLINE_ int size() const {
if (!_ptr)
return 0;
int* size = _get_size();
if (size)
return *size;
else
return *reinterpret_cast<int*>(((uint8_t*)(_ptr))+sizeof(SafeRefCount));
return 0;
}
_FORCE_INLINE_ bool empty() const { return _ptr == 0; }
Error resize(int p_size);
@ -174,7 +174,7 @@ void Vector<T>::_unref(void *p_data) {
if (!p_data)
return;
SafeRefCount *src = reinterpret_cast<SafeRefCount*>(p_data);
SafeRefCount *src = reinterpret_cast<SafeRefCount*>((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
if (!src->unref())
return; // still in use
@ -189,7 +189,7 @@ void Vector<T>::_unref(void *p_data) {
}
// free mem
memfree(p_data);
memfree((uint8_t*)p_data-sizeof(int)-sizeof(SafeRefCount));
}
@ -201,7 +201,8 @@ void Vector<T>::_copy_on_write() {
if (_get_refcount()->get() > 1 ) {
/* in use by more than me */
SafeRefCount *src_new=(SafeRefCount *)memalloc(_get_alloc_size(*_get_size()));
void* mem_new = memalloc(_get_alloc_size(*_get_size()));
SafeRefCount *src_new=(SafeRefCount *)mem_new;
src_new->init();
int * _size = (int*)(src_new+1);
*_size=*_get_size();
@ -215,7 +216,7 @@ void Vector<T>::_copy_on_write() {
}
_unref(_ptr);
_ptr=src_new;
_ptr=_data;
}
}
@ -260,16 +261,17 @@ Error Vector<T>::resize(int p_size) {
if (size()==0) {
// alloc from scratch
_ptr = (T*)memalloc(_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptr ,ERR_OUT_OF_MEMORY);
void* ptr=memalloc(_get_alloc_size(p_size));
ERR_FAIL_COND_V( !ptr ,ERR_OUT_OF_MEMORY);
_ptr=(T*)((uint8_t*)ptr+sizeof(int)+sizeof(SafeRefCount));
_get_refcount()->init(); // init refcount
*_get_size()=0; // init size (currently, none)
} else {
void *_ptrnew = (T*)memrealloc(_ptr,_get_alloc_size(p_size));
void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=_ptrnew;
_ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
}
// construct the newly created elements
@ -291,10 +293,10 @@ Error Vector<T>::resize(int p_size) {
t->~T();
}
void *_ptrnew = (T*)memrealloc(_ptr,_get_alloc_size(p_size));
void *_ptrnew = (T*)memrealloc((uint8_t*)_ptr-sizeof(int)-sizeof(SafeRefCount),_get_alloc_size(p_size));
ERR_FAIL_COND_V( !_ptrnew ,ERR_OUT_OF_MEMORY);
_ptr=_ptrnew;
_ptr=(T*)((uint8_t*)_ptrnew+sizeof(int)+sizeof(SafeRefCount));
*_get_size()=p_size;

Binary file not shown.

View file

@ -15053,14 +15053,13 @@ returns:= "username=user&amp;password=pass"
<description>
</description>
</method>
<method name="can_move_to">
<method name="can_teleport_to">
<return type="bool">
</return>
<argument index="0" name="position" type="Vector3">
</argument>
<argument index="1" name="arg1" type="bool">
</argument>
<description>
Returns whether the KinematicBody can be teleported to the destination given as an argument, checking all collision shapes of the body against potential colliders at the destination.
</description>
</method>
<method name="is_colliding" qualifiers="const">
@ -26960,7 +26959,7 @@ This method controls whether the position between two cached points is interpola
Lazy (non-greedy) quantifiers [code]*?[/code]
Begining [code]^[/code] and end [code]$[/code] anchors
Alternation [code]|[/code]
Backreferences [code]\1[/code] to [code]\9[/code]
Backreferences [code]\1[/code] and [code]\g{1}[/code]
POSIX character classes [code][[:alnum:]][/code]
Lookahead [code](?=)[/code], [code](?!)[/code] and lookbehind [code](?&lt;=)[/code], [code](?&lt;!)[/code]
ASCII [code]\xFF[/code] and Unicode [code]\uFFFF[/code] code points (in a style similar to Python)
@ -26972,9 +26971,10 @@ This method controls whether the position between two cached points is interpola
</return>
<argument index="0" name="pattern" type="String">
</argument>
<argument index="1" name="expanded" type="bool" default="true">
<argument index="1" name="capture" type="int" default="9">
</argument>
<description>
Compiles and assign the regular expression pattern to use. The limit on the number of capturing groups can be specified or made unlimited if negative.
</description>
</method>
<method name="find" qualifiers="const">

View file

@ -9169,10 +9169,23 @@ void RasterizerGLES2::_canvas_item_render_commands(CanvasItem *p_item,CanvasItem
//glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
//current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
int x = current_clip->final_clip_rect.pos.x;
int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
int x;
int y;
int w;
int h;
if (current_rt) {
x = current_clip->final_clip_rect.pos.x;
y = current_clip->final_clip_rect.pos.y;
w = current_clip->final_clip_rect.size.x;
h = current_clip->final_clip_rect.size.y;
}
else {
x = current_clip->final_clip_rect.pos.x;
y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
w = current_clip->final_clip_rect.size.x;
h = current_clip->final_clip_rect.size.y;
}
glScissor(x,y,w,h);
@ -9362,10 +9375,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
*/
int x = current_clip->final_clip_rect.pos.x;
int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
int x;
int y;
int w;
int h;
if (current_rt) {
x = current_clip->final_clip_rect.pos.x;
y = current_clip->final_clip_rect.pos.y;
w = current_clip->final_clip_rect.size.x;
h = current_clip->final_clip_rect.size.y;
}
else {
x = current_clip->final_clip_rect.pos.x;
y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
w = current_clip->final_clip_rect.size.x;
h = current_clip->final_clip_rect.size.y;
}
glScissor(x,y,w,h);
@ -9667,10 +9693,23 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
//glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
//current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
int x = current_clip->final_clip_rect.pos.x;
int y = window_size.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.y);
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
int x;
int y;
int w;
int h;
if (current_rt) {
x = current_clip->final_clip_rect.pos.x;
y = current_clip->final_clip_rect.pos.y;
w = current_clip->final_clip_rect.size.x;
h = current_clip->final_clip_rect.size.y;
}
else {
x = current_clip->final_clip_rect.pos.x;
y = window_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
w = current_clip->final_clip_rect.size.x;
h = current_clip->final_clip_rect.size.y;
}
glScissor(x,y,w,h);

View file

@ -1,5 +1,7 @@
# NREX: Node RegEx
Version 0.1
Small node-based regular expression library. It only does text pattern
matchhing, not replacement. To use add the files `nrex.hpp`, `nrex.cpp`
and `nrex_config.h` to your project and follow the example:
@ -32,7 +34,7 @@ Currently supported features:
* Unicode `\uFFFF` code points
* Positive `(?=)` and negative `(?!)` lookahead
* Positive `(?<=)` and negative `(?<!)` lookbehind (fixed length and no alternations)
* Backreferences `\1` to `\9` (with option to expand to `\99`)
* Backreferences `\1` and `\g{1}` (limited by default to 9 - can be unlimited)
## License

View file

@ -1,4 +1,5 @@
// NREX: Node RegEx
// Version 0.1
//
// Copyright (c) 2015, Zher Huei Lee
// All rights reserved.
@ -299,6 +300,10 @@ struct nrex_node_group : public nrex_node
{
length = 1;
}
if (mode == LookAhead || mode == LookBehind)
{
quantifiable = false;
}
}
virtual ~nrex_node_group()
@ -322,6 +327,10 @@ struct nrex_node_group : public nrex_node
int offset = 0;
if (mode == LookBehind)
{
if (pos < length)
{
return -1;
}
offset = length;
}
int res = childset[i]->test(s, pos - offset);
@ -450,7 +459,7 @@ struct nrex_node_char : public nrex_node
int test(nrex_search* s, int pos) const
{
if (s->end == pos || s->at(pos) != ch)
if (s->end <= pos || 0 > pos || s->at(pos) != ch)
{
return -1;
}
@ -473,7 +482,7 @@ struct nrex_node_range : public nrex_node
int test(nrex_search* s, int pos) const
{
if (s->end == pos)
if (s->end <= pos || 0 > pos)
{
return -1;
}
@ -555,7 +564,7 @@ struct nrex_node_class : public nrex_node
int test(nrex_search* s, int pos) const
{
if (s->end == pos)
if (s->end <= pos || 0 > pos)
{
return -1;
}
@ -727,7 +736,7 @@ struct nrex_node_shorthand : public nrex_node
int test(nrex_search* s, int pos) const
{
if (s->end == pos)
if (s->end <= pos || 0 > pos)
{
return -1;
}
@ -811,16 +820,12 @@ struct nrex_node_quantifier : public nrex_node
int test(nrex_search* s, int pos) const
{
return test_step(s, pos, 1);
return test_step(s, pos, 0, pos);
}
int test_step(nrex_search* s, int pos, int level) const
int test_step(nrex_search* s, int pos, int level, int start) const
{
if (max == 0)
{
return pos;
}
if ((max >= 1 && level > max) || pos > s->end)
if (pos > s->end)
{
return -1;
}
@ -840,14 +845,26 @@ struct nrex_node_quantifier : public nrex_node
return res;
}
}
int res = child->test(s, pos);
if (s->complete)
if (max >= 0 && level > max)
{
return res;
return -1;
}
if (level > 1 && level > min + 1 && pos == start)
{
return -1;
}
int res = pos;
if (level >= 1)
{
res = child->test(s, pos);
if (s->complete)
{
return res;
}
}
if (res >= 0)
{
int res_step = test_step(s, res, level + 1);
int res_step = test_step(s, res, level + 1, start);
if (res_step >= 0)
{
return res_step;
@ -983,6 +1000,13 @@ nrex::nrex()
{
}
nrex::nrex(const nrex_char* pattern, int captures)
: _capturing(0)
, _root(NULL)
{
compile(pattern, captures);
}
nrex::~nrex()
{
if (_root)
@ -1008,10 +1032,14 @@ void nrex::reset()
int nrex::capture_size() const
{
return _capturing + 1;
if (_root)
{
return _capturing + 1;
}
return 0;
}
bool nrex::compile(const nrex_char* pattern, bool extended)
bool nrex::compile(const nrex_char* pattern, int captures)
{
reset();
nrex_node_group* root = NREX_NEW(nrex_node_group(_capturing));
@ -1053,7 +1081,7 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
NREX_COMPILE_ERROR("unrecognised qualifier for group");
}
}
else if ((!extended && _capturing < 9) || (extended && _capturing < 99))
else if (captures >= 0 && _capturing < captures)
{
nrex_node_group* group = NREX_NEW(nrex_node_group(++_capturing));
stack.top()->add_child(group);
@ -1190,15 +1218,6 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
}
else if (nrex_is_quantifier(c[0]))
{
if (stack.top()->back == NULL || !stack.top()->back->quantifiable)
{
if (c[0] == '{')
{
stack.top()->add_child(NREX_NEW(nrex_node_char('{')));
continue;
}
NREX_COMPILE_ERROR("element not quantifiable");
}
int min = 0;
int max = -1;
bool valid_quantifier = true;
@ -1270,6 +1289,10 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
}
if (valid_quantifier)
{
if (stack.top()->back == NULL || !stack.top()->back->quantifiable)
{
NREX_COMPILE_ERROR("element not quantifiable");
}
nrex_node_quantifier* quant = NREX_NEW(nrex_node_quantifier(min, max));
if (min == max)
{
@ -1323,20 +1346,26 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
stack.top()->add_child(NREX_NEW(nrex_node_shorthand(c[1])));
++c;
}
else if ('1' <= c[1] && c[1] <= '9')
else if (('1' <= c[1] && c[1] <= '9') || (c[1] == 'g' && c[2] == '{'))
{
int ref = 0;
if (extended && '0' <= c[2] && c[2] <= '9')
bool unclosed = false;
if (c[1] == 'g')
{
ref = int(c[1] - '0') * 10 + int(c[2] - '0');
unclosed = true;
c = &c[2];
}
else
while ('0' <= c[1] && c[1] <= '9')
{
ref = int(c[1] - '0');
ref = ref * 10 + int(c[1] - '0');
++c;
}
if (ref > _capturing)
if (c[1] == '}')
{
unclosed = false;
++c;
}
if (ref > _capturing || ref <= 0 || unclosed)
{
NREX_COMPILE_ERROR("backreference to non-existent capture");
}
@ -1377,6 +1406,10 @@ bool nrex::compile(const nrex_char* pattern, bool extended)
bool nrex::match(const nrex_char* str, nrex_result* captures, int offset, int end) const
{
if (!_root)
{
return false;
}
nrex_search s(str, captures);
if (end >= offset)
{
@ -1386,7 +1419,7 @@ bool nrex::match(const nrex_char* str, nrex_result* captures, int offset, int en
{
s.end = NREX_STRLEN(str);
}
for (int i = offset; i < s.end; ++i)
for (int i = offset; i <= s.end; ++i)
{
for (int c = 0; c <= _capturing; ++c)
{

View file

@ -1,4 +1,5 @@
// NREX: Node RegEx
// Version 0.1
//
// Copyright (c) 2015, Zher Huei Lee
// All rights reserved.
@ -59,7 +60,32 @@ class nrex
int _capturing;
nrex_node* _root;
public:
/*!
* \brief Initialises an empty regex container
*/
nrex();
/*!
* \brief Initialises and compiles the regex pattern
*
* This calls nrex::compile() with the same arguments. To check whether
* the compilation was successfull, use nrex::valid().
*
* If the NREX_THROW_ERROR was defined it would automatically throw a
* runtime error nrex_compile_error if it encounters a problem when
* parsing the pattern.
*
* \param pattern The regex pattern
* \param captures The maximum number of capture groups to allow. Any
* extra would be converted to non-capturing groups.
* If negative, no limit would be imposed. Defaults
* to 9.
*
* \see nrex::compile()
*/
nrex(const nrex_char* pattern, int captures = 9);
~nrex();
/*!
@ -78,9 +104,9 @@ class nrex
*
* This is used to provide the array size of the captures needed for
* nrex::match() to work. The size is actually the number of capture
* groups + one for the matching of the entire pattern. The result is
* always capped at 10 or 100, depending on the extend option given in
* nrex::compile() (default 10).
* groups + one for the matching of the entire pattern. This can be
* capped using the extra argument given in nrex::compile()
* (default 10).
*
* \return The number of captures
*/
@ -97,12 +123,13 @@ class nrex
* parsing the pattern.
*
* \param pattern The regex pattern
* \param extended If true, raises the limit on number of capture
* groups and back-references to 99. Otherwise limited
* to 9. Defaults to false.
* \param captures The maximum number of capture groups to allow. Any
* extra would be converted to non-capturing groups.
* If negative, no limit would be imposed. Defaults
* to 9.
* \return True if the pattern was succesfully compiled
*/
bool compile(const nrex_char* pattern, bool extended = false);
bool compile(const nrex_char* pattern, int captures = 9);
/*!
* \brief Uses the pattern to search through the provided string

View file

@ -15,7 +15,7 @@
void RegEx::_bind_methods() {
ObjectTypeDB::bind_method(_MD("compile","pattern", "expanded"),&RegEx::compile, DEFVAL(true));
ObjectTypeDB::bind_method(_MD("compile","pattern", "capture"),&RegEx::compile, DEFVAL(9));
ObjectTypeDB::bind_method(_MD("find","text","start","end"),&RegEx::find, DEFVAL(0), DEFVAL(-1));
ObjectTypeDB::bind_method(_MD("clear"),&RegEx::clear);
ObjectTypeDB::bind_method(_MD("is_valid"),&RegEx::is_valid);
@ -68,11 +68,11 @@ String RegEx::get_capture(int capture) const {
}
Error RegEx::compile(const String& p_pattern, bool expanded) {
Error RegEx::compile(const String& p_pattern, int capture) {
clear();
exp.compile(p_pattern.c_str(), expanded);
exp.compile(p_pattern.c_str(), capture);
ERR_FAIL_COND_V( !exp.valid(), FAILED );

View file

@ -36,7 +36,7 @@ public:
bool is_valid() const;
int get_capture_count() const;
String get_capture(int capture) const;
Error compile(const String& p_pattern, bool expanded = false);
Error compile(const String& p_pattern, int capture = 9);
int find(const String& p_text, int p_start = 0, int p_end = -1) const;
RegEx();

View file

@ -1,5 +1,13 @@
Import('env')
ed_gl_set='#include "os_unix.h"\n'
ed_gl_set+='String OS_Unix::get_global_settings_path() const {\n'
ed_gl_set+='\treturn "' + env["unix_global_settings_path"]+'";\n'
ed_gl_set+='}\n'
f = open("os_unix_global_settings_path.cpp","wb")
f.write(ed_gl_set)
f.close()
env.add_source_files(env.drivers_sources,"*.cpp")
Export('env')

View file

@ -477,6 +477,14 @@ String OS_Unix::get_data_dir() const {
}
String OS_Unix::get_installed_templates_path() const {
String p=get_global_settings_path();
if (p!="")
return p+"/templates/";
else
return "";
}
String OS_Unix::get_executable_path() const {
#ifdef __linux__

View file

@ -64,6 +64,8 @@ protected:
String stdin_buf;
String get_global_settings_path() const;
public:
@ -111,6 +113,7 @@ public:
virtual void debug_break();
virtual String get_installed_templates_path() const;
virtual String get_executable_path() const;
virtual String get_data_dir() const;

View file

@ -774,20 +774,15 @@ void GDTokenizerText::_advance() {
{Variant::INT,"int"},
{Variant::REAL,"float"},
{Variant::STRING,"String"},
{Variant::VECTOR2,"vec2"},
{Variant::VECTOR2,"Vector2"},
{Variant::RECT2,"Rect2"},
{Variant::MATRIX32,"Matrix32"},
{Variant::MATRIX32,"mat32"},
{Variant::VECTOR3,"vec3"},
{Variant::VECTOR3,"Vector3"},
{Variant::_AABB,"AABB"},
{Variant::_AABB,"Rect3"},
{Variant::PLANE,"Plane"},
{Variant::QUAT,"Quat"},
{Variant::MATRIX3,"mat3"},
{Variant::MATRIX3,"Matrix3"},
{Variant::TRANSFORM,"trn"},
{Variant::TRANSFORM,"Transform"},
{Variant::COLOR,"Color"},
{Variant::IMAGE,"Image"},
@ -795,7 +790,6 @@ void GDTokenizerText::_advance() {
{Variant::OBJECT,"Object"},
{Variant::INPUT_EVENT,"InputEvent"},
{Variant::NODE_PATH,"NodePath"},
{Variant::DICTIONARY,"dict"},
{Variant::DICTIONARY,"Dictionary"},
{Variant::ARRAY,"Array"},
{Variant::RAW_ARRAY,"RawArray"},

View file

@ -1020,18 +1020,24 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
EditorProgress ep("export","Exporting for Android",104);
String apk_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (p_debug) {
src_apk=custom_debug_package!=""?custom_debug_package:apk_path+"android_debug.apk";
} else {
src_apk=custom_release_package!=""?custom_release_package:apk_path+"android_release.apk";
if (p_debug)
src_apk=custom_debug_package;
else
src_apk=custom_release_package;
if (src_apk=="") {
String err;
if (p_debug) {
src_apk=find_export_template("android_debug.apk", &err);
} else {
src_apk=find_export_template("android_release.apk", &err);
}
if (src_apk=="") {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
}
FileAccess *src_f=NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@ -1659,10 +1665,7 @@ bool EditorExportPlatformAndroid::can_export(String *r_error) const {
err+="Debug Keystore not configured in editor settings.\n";
}
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (!FileAccess::exists(exe_path+"android_debug.apk") || !FileAccess::exists(exe_path+"android_release.apk")) {
if (!exists_export_template("android_debug.apk") || !exists_export_template("android_release.apk")) {
valid=false;
err+="No export templates found.\nDownload and install export templates.\n";
}

View file

@ -275,10 +275,16 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
EditorProgress ep("export","Exporting for BlackBerry 10",104);
String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
String src_template=custom_package!=""?custom_package:template_path.plus_file("bb10.zip");
String src_template=custom_package;
if (src_template=="") {
String err;
src_template = find_export_template("bb10.zip", &err);
if (src_template=="") {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
}
FileAccess *src_f=NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@ -733,9 +739,7 @@ bool EditorExportPlatformBB10::can_export(String *r_error) const {
err+="Blackberry host tools not configured in editor settings.\n";
}
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (!FileAccess::exists(exe_path+"bb10.zip")) {
if (!exists_export_template("bb10.zip")) {
valid=false;
err+="No export template found.\nDownload and install export templates.\n";
}

View file

@ -205,18 +205,24 @@ Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool
EditorProgress ep("export","Exporting for javascript",104);
String template_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (p_debug) {
src_template=custom_debug_package!=""?custom_debug_package:template_path+"javascript_debug.zip";
} else {
src_template=custom_release_package!=""?custom_release_package:template_path+"javascript_release.zip";
if (p_debug)
src_template=custom_debug_package;
else
src_template=custom_release_package;
if (src_template=="") {
String err;
if (p_debug) {
src_template=find_export_template("javascript_debug.zip", &err);
} else {
src_template=find_export_template("javascript_release.zip", &err);
}
if (src_template=="") {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
}
FileAccess *src_f=NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
@ -337,9 +343,8 @@ bool EditorExportPlatformJavaScript::can_export(String *r_error) const {
bool valid=true;
String err;
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (!FileAccess::exists(exe_path+"javascript_debug.zip") || !FileAccess::exists(exe_path+"javascript_release.zip")) {
if (!exists_export_template("javascript_debug.zip") || !exists_export_template("javascript_release.zip")) {
valid=false;
err+="No export templates found.\nDownload and install export templates.\n";
}

View file

@ -251,15 +251,19 @@ Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug
EditorProgress ep("export","Exporting for OSX",104);
String pkg_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/osx.zip";
if (p_debug) {
src_pkg=custom_debug_package!=""?custom_debug_package:pkg_path;
} else {
src_pkg=custom_release_package!=""?custom_release_package:pkg_path;
if (p_debug)
src_pkg=custom_debug_package;
else
src_pkg=custom_release_package;
if (src_pkg=="") {
String err;
src_pkg=find_export_template("osx.zip", &err);
if (src_pkg=="") {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
}
@ -464,9 +468,8 @@ bool EditorExportPlatformOSX::can_export(String *r_error) const {
bool valid=true;
String err;
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (!FileAccess::exists(exe_path+"osx.zip")) {
if (!exists_export_template("osx.zip")) {
valid=false;
err+="No export templates found.\nDownload and install export templates.\n";
}

View file

@ -1,6 +1,7 @@
import os
import sys
import platform
def is_active():
@ -147,7 +148,9 @@ def configure(env):
env.Append(CPPFLAGS=['-DOPENGL_ENABLED','-DGLEW_ENABLED'])
env.Append(CPPFLAGS=["-DALSA_ENABLED"])
if platform.platform() == 'Linux':
env.Append(CPPFLAGS=["-DALSA_ENABLED"])
env.Append(LIBS=['asound'])
if (env["pulseaudio"]=="yes"):
if not os.system("pkg-config --exists libpulse-simple"):
@ -158,7 +161,7 @@ def configure(env):
print("PulseAudio development libraries not found, disabling driver")
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL'])
env.Append(LIBS=['GL', 'GLU', 'pthread','asound','z']) #TODO detect linux/BSD!
env.Append(LIBS=['GL', 'GLU', 'pthread', 'z'])
#env.Append(CPPFLAGS=['-DMPC_FIXED_POINT'])
#host compiler is default..

View file

@ -32,6 +32,7 @@
#include "key_mapping_x11.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "print_string.h"
#include "servers/physics/physics_server_sw.h"
#include "errno.h"
@ -1672,7 +1673,7 @@ void OS_X11::close_joystick(int p_id) {
};
void OS_X11::probe_joystick(int p_id) {
#ifndef __FreeBSD__
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
if (p_id == -1) {
@ -1727,7 +1728,7 @@ void OS_X11::move_window_to_foreground() {
}
void OS_X11::process_joysticks() {
#ifndef __FreeBSD__
#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
int bytes;
js_event events[32];
InputEvent ievent;

View file

@ -29,7 +29,7 @@
#ifdef __linux__
#include <alloca.h>
#endif
#ifdef __FreeBSD__
#if defined(__FreeBSD__) || defined(__OpenBSD__)
#include <stdlib.h>
#endif

View file

@ -309,6 +309,15 @@ void CanvasItem::hide() {
_change_notify("visibility/visible");
}
void CanvasItem::set_hidden(bool p_hidden) {
if (hidden == p_hidden) {
return;
}
_set_visible_(!p_hidden);
}
Variant CanvasItem::edit_get_state() const {
@ -1043,6 +1052,7 @@ void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_hidden"),&CanvasItem::is_hidden);
ObjectTypeDB::bind_method(_MD("show"),&CanvasItem::show);
ObjectTypeDB::bind_method(_MD("hide"),&CanvasItem::hide);
ObjectTypeDB::bind_method(_MD("set_hidden","hidden"),&CanvasItem::set_hidden);
ObjectTypeDB::bind_method(_MD("update"),&CanvasItem::update);

View file

@ -190,6 +190,7 @@ public:
bool is_hidden() const;
void show();
void hide();
void set_hidden(bool p_hidden);
void update();

View file

@ -1073,7 +1073,7 @@ Vector3 KinematicBody::move_to(const Vector3& p_position) {
return move(p_position-get_global_transform().origin);
}
bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) {
bool KinematicBody::can_teleport_to(const Vector3& p_position) {
ERR_FAIL_COND_V(!is_inside_tree(),false);
PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space());
@ -1089,25 +1089,18 @@ bool KinematicBody::can_move_to(const Vector3& p_position, bool p_discrete) {
if (collide_character)
mask|=PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
Vector3 motion = p_position-get_global_transform().origin;
Transform xform=get_global_transform();
if (true || p_discrete) {
xform.origin+=motion;
motion=Vector3();
}
xform.origin=p_position;
Set<RID> exclude;
exclude.insert(get_rid());
//fill exclude list..
for(int i=0;i<get_shape_count();i++) {
if (is_shape_set_as_trigger(i))
continue;
bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,0,exclude,get_layer_mask(),mask);
bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),0,NULL,1,exclude,get_layer_mask(),mask);
if (col)
return false;
}
@ -1205,7 +1198,7 @@ void KinematicBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("move","rel_vec"),&KinematicBody::move);
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody::move_to);
ObjectTypeDB::bind_method(_MD("can_move_to","position"),&KinematicBody::can_move_to);
ObjectTypeDB::bind_method(_MD("can_teleport_to","position"),&KinematicBody::can_teleport_to);
ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody::is_colliding);

View file

@ -304,7 +304,7 @@ public:
Vector3 move(const Vector3& p_motion);
Vector3 move_to(const Vector3& p_position);
bool can_move_to(const Vector3& p_position,bool p_discrete=false);
bool can_teleport_to(const Vector3& p_position);
bool is_colliding() const;
Vector3 get_collision_pos() const;
Vector3 get_collision_normal() const;

View file

@ -594,6 +594,15 @@ bool Spatial::is_hidden() const{
return !data.visible;
}
void Spatial::set_hidden(bool p_hidden) {
if (data.visible != p_hidden) {
return;
}
_set_visible_(!p_hidden);
}
void Spatial::_set_visible_(bool p_visible) {
if (p_visible)
@ -742,6 +751,7 @@ void Spatial::_bind_methods() {
ObjectTypeDB::bind_method(_MD("hide"), &Spatial::hide);
ObjectTypeDB::bind_method(_MD("is_visible"), &Spatial::is_visible);
ObjectTypeDB::bind_method(_MD("is_hidden"), &Spatial::is_hidden);
ObjectTypeDB::bind_method(_MD("set_hidden","hidden"), &Spatial::set_hidden);
ObjectTypeDB::bind_method(_MD("_set_visible_"), &Spatial::_set_visible_);
ObjectTypeDB::bind_method(_MD("_is_visible_"), &Spatial::_is_visible_);

View file

@ -191,6 +191,7 @@ public:
void hide();
bool is_visible() const;
bool is_hidden() const;
void set_hidden(bool p_hidden);
#ifdef TOOLS_ENABLED
void set_import_transform(const Transform& p_transform) ;

View file

@ -382,7 +382,7 @@ void BodySW::set_space(SpaceSW *p_space){
}
void BodySW::_compute_area_gravity(const AreaSW *p_area) {
void BodySW::_compute_area_gravity_and_dampenings(const AreaSW *p_area) {
if (p_area->is_gravity_point()) {
if(p_area->get_gravity_distance_scale() > 0) {
@ -394,6 +394,9 @@ void BodySW::_compute_area_gravity(const AreaSW *p_area) {
} else {
gravity += p_area->get_gravity_vector() * p_area->get_gravity();
}
area_linear_damp += p_area->get_linear_damp();
area_angular_damp += p_area->get_angular_damp();
}
void BodySW::integrate_forces(real_t p_step) {
@ -409,13 +412,15 @@ void BodySW::integrate_forces(real_t p_step) {
int ac = areas.size();
bool replace = false;
gravity=Vector3(0,0,0);
gravity = Vector3(0,0,0);
area_linear_damp = 0;
area_angular_damp = 0;
if (ac) {
areas.sort();
const AreaCMP *aa = &areas[0];
damp_area = aa[ac-1].area;
for(int i=ac-1;i>=0;i--) {
_compute_area_gravity(aa[i].area);
_compute_area_gravity_and_dampenings(aa[i].area);
if (aa[i].area->get_space_override_mode() == PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE) {
replace = true;
break;
@ -424,20 +429,21 @@ void BodySW::integrate_forces(real_t p_step) {
}
if( !replace ) {
_compute_area_gravity(def_area);
_compute_area_gravity_and_dampenings(def_area);
}
gravity*=gravity_scale;
// If less than 0, override dampenings with that of the Body
if (angular_damp>=0)
area_angular_damp=angular_damp;
else
area_angular_damp=damp_area->get_angular_damp();
//else
// area_angular_damp=damp_area->get_angular_damp();
if (linear_damp>=0)
area_linear_damp=linear_damp;
else
area_linear_damp=damp_area->get_linear_damp();
//else
// area_linear_damp=damp_area->get_linear_damp();
Vector3 motion;

View file

@ -130,7 +130,7 @@ class BodySW : public CollisionObjectSW {
BodySW *island_next;
BodySW *island_list_next;
_FORCE_INLINE_ void _compute_area_gravity(const AreaSW *p_area);
_FORCE_INLINE_ void _compute_area_gravity_and_dampenings(const AreaSW *p_area);
_FORCE_INLINE_ void _update_inertia_tensor();

View file

@ -175,13 +175,15 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Transfo
if (!CollisionSolverSW::solve_static(shape,p_xform,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), NULL,NULL,NULL,p_margin,0))
continue;
r_results[cc].collider_id=col_obj->get_instance_id();
if (r_results[cc].collider_id!=0)
r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
else
r_results[cc].collider=NULL;
r_results[cc].rid=col_obj->get_self();
r_results[cc].shape=shape_idx;
if (r_results) {
r_results[cc].collider_id=col_obj->get_instance_id();
if (r_results[cc].collider_id!=0)
r_results[cc].collider=ObjectDB::get_instance(r_results[cc].collider_id);
else
r_results[cc].collider=NULL;
r_results[cc].rid=col_obj->get_self();
r_results[cc].shape=shape_idx;
}
cc++;

View file

@ -380,7 +380,7 @@ void Body2DSW::set_space(Space2DSW *p_space){
}
void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) {
void Body2DSW::_compute_area_gravity_and_dampenings(const Area2DSW *p_area) {
if (p_area->is_gravity_point()) {
if(p_area->get_gravity_distance_scale() > 0) {
@ -393,6 +393,8 @@ void Body2DSW::_compute_area_gravity(const Area2DSW *p_area) {
gravity += p_area->get_gravity_vector() * p_area->get_gravity();
}
area_linear_damp += p_area->get_linear_damp();
area_angular_damp += p_area->get_angular_damp();
}
void Body2DSW::integrate_forces(real_t p_step) {
@ -406,13 +408,15 @@ void Body2DSW::integrate_forces(real_t p_step) {
int ac = areas.size();
bool replace = false;
gravity=Vector2(0,0);
gravity = Vector2(0,0);
area_angular_damp = 0;
area_linear_damp = 0;
if (ac) {
areas.sort();
const AreaCMP *aa = &areas[0];
damp_area = aa[ac-1].area;
for(int i=ac-1;i>=0;i--) {
_compute_area_gravity(aa[i].area);
_compute_area_gravity_and_dampenings(aa[i].area);
if (aa[i].area->get_space_override_mode() == Physics2DServer::AREA_SPACE_OVERRIDE_REPLACE) {
replace = true;
break;
@ -420,19 +424,20 @@ void Body2DSW::integrate_forces(real_t p_step) {
}
}
if( !replace ) {
_compute_area_gravity(def_area);
_compute_area_gravity_and_dampenings(def_area);
}
gravity*=gravity_scale;
// If less than 0, override dampenings with that of the Body2D
if (angular_damp>=0)
area_angular_damp=angular_damp;
else
area_angular_damp=damp_area->get_angular_damp();
area_angular_damp = angular_damp;
//else
// area_angular_damp=damp_area->get_angular_damp();
if (linear_damp>=0)
area_linear_damp=linear_damp;
else
area_linear_damp=damp_area->get_linear_damp();
area_linear_damp = linear_damp;
//else
// area_linear_damp=damp_area->get_linear_damp();
Vector2 motion;
bool do_motion=false;

View file

@ -132,7 +132,7 @@ class Body2DSW : public CollisionObject2DSW {
Body2DSW *island_next;
Body2DSW *island_list_next;
_FORCE_INLINE_ void _compute_area_gravity(const Area2DSW *p_area);
_FORCE_INLINE_ void _compute_area_gravity_and_dampenings(const Area2DSW *p_area);
friend class Physics2DDirectBodyStateSW; // i give up, too many functions to expose

View file

@ -2341,19 +2341,27 @@ Error ShaderLanguage::parse_flow_if(Parser& parser,Node *p_parent,Node **r_state
parser.advance();
if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
parser.set_error("Expected statement block after 'if()'");
return ERR_PARSE_ERROR;
}
Node *substatement=NULL;
err = parse_statement(parser,cf,&substatement);
if (err)
return err;
cf->statements.push_back(substatement);
if (parser.get_token_type()==TK_CF_ELSE) {
parser.advance();
if (parser.get_token_type()!=TK_CURLY_BRACKET_OPEN) {
parser.set_error("Expected statement block after 'else'");
return ERR_PARSE_ERROR;
}
substatement=NULL;
err = parse_statement(parser,cf,&substatement);
if (err)

View file

@ -399,6 +399,40 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
}
String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
String user_file = EditorSettings::get_singleton()->get_settings_path()
+"/templates/"+template_file_name;
String system_file=OS::get_singleton()->get_installed_templates_path();
bool has_system_path=(system_file!="");
system_file+=template_file_name;
// Prefer user file
if (FileAccess::exists(user_file)) {
return user_file;
}
// Now check system file
if (has_system_path) {
if (FileAccess::exists(system_file)) {
return system_file;
}
}
// Not found
if (err) {
*err+="No export template found at \""+user_file+"\"";
if (has_system_path)
*err+="\n or \""+system_file+"\".";
else
*err+=".";
}
return "";
}
bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const {
return find_export_template(template_file_name,err)!="";
}
///////////////////////////////////////
@ -1131,19 +1165,32 @@ Error EditorExportPlatformPC::export_project(const String& p_path, bool p_debug,
ep.step("Setting Up..",0);
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (use64) {
if (p_debug)
exe_path=custom_debug_binary!=""?custom_debug_binary:exe_path+debug_binary64;
else
exe_path=custom_release_binary!=""?custom_release_binary:exe_path+release_binary64;
} else {
String exe_path="";
if (p_debug)
exe_path=custom_debug_binary!=""?custom_debug_binary:exe_path+debug_binary32;
else
exe_path=custom_release_binary!=""?custom_release_binary:exe_path+release_binary32;
if (p_debug)
exe_path=custom_debug_binary;
else
exe_path=custom_release_binary;
if (exe_path=="") {
String fname;
if (use64) {
if (p_debug)
fname=debug_binary64;
else
fname=release_binary64;
} else {
if (p_debug)
fname=debug_binary32;
else
fname=release_binary32;
}
String err="";
exe_path=find_export_template(fname,&err);
if (exe_path=="") {
EditorNode::add_io_error(err);
return ERR_FILE_CANT_READ;
}
}
FileAccess *src_exe=FileAccess::open(exe_path,FileAccess::READ);
@ -1207,14 +1254,12 @@ bool EditorExportPlatformPC::can_export(String *r_error) const {
String err;
bool valid=true;
String exe_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/";
if (use64 && (!FileAccess::exists(exe_path+debug_binary64) || !FileAccess::exists(exe_path+release_binary64))) {
if (use64 && (!exists_export_template(debug_binary64)) || !exists_export_template(release_binary64)) {
valid=false;
err="No 64 bits export templates found.\nDownload and install export templates.\n";
}
if (!use64 && (!FileAccess::exists(exe_path+debug_binary32) || !FileAccess::exists(exe_path+release_binary32))) {
if (!use64 && (!exists_export_template(debug_binary32) || !exists_export_template(release_binary32))) {
valid=false;
err="No 32 bits export templates found.\nDownload and install export templates.\n";
}

View file

@ -86,6 +86,8 @@ protected:
Vector<uint8_t> get_exported_file_default(String& p_fname) const;
virtual Vector<uint8_t> get_exported_file(String& p_fname) const;
virtual Vector<StringName> get_dependencies(bool p_bundles) const;
virtual String find_export_template(String template_file_name, String *err=NULL) const;
virtual bool exists_export_template(String template_file_name, String *err=NULL) const;
struct TempData {

View file

@ -0,0 +1,59 @@
/*************************************************************************/
/* editor_node.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "editor_layout_dialog.h"
#include "object_type_db.h"
void EditorLayoutDialog::clear_layout_name() {
layout_name->clear();
}
void EditorLayoutDialog::ok_pressed() {
if (layout_name->get_text()!="") {
emit_signal("layout_selected", layout_name->get_text());
}
}
void EditorLayoutDialog::_bind_methods() {
ADD_SIGNAL(MethodInfo("layout_selected",PropertyInfo( Variant::STRING,"layout_name")));
}
EditorLayoutDialog::EditorLayoutDialog()
{
layout_name = memnew( LineEdit );
layout_name->set_margin(MARGIN_TOP,5);
layout_name->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_BEGIN,5);
layout_name->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,5);
add_child(layout_name);
move_child(layout_name, get_label()->get_index()+1);
}

View file

@ -0,0 +1,53 @@
/*************************************************************************/
/* editor_layout_dialog.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
/* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#ifndef EDITOR_LAYOUT_DIALOG_H
#define EDITOR_LAYOUT_DIALOG_H
#include "scene/gui/dialogs.h"
#include "scene/gui/line_edit.h"
class EditorLayoutDialog : public ConfirmationDialog {
OBJ_TYPE( EditorLayoutDialog, ConfirmationDialog );
LineEdit *layout_name;
protected:
static void _bind_methods();
virtual void ok_pressed();
public:
void clear_layout_name();
EditorLayoutDialog();
};
#endif // EDITOR_LAYOUT_DIALOG_H

View file

@ -543,7 +543,6 @@ void EditorNode::save_resource_as(const Ref<Resource>& p_resource) {
}
void EditorNode::_menu_option(int p_option) {
_menu_option_confirm(p_option,false);
@ -1409,6 +1408,69 @@ void EditorNode::_dialog_action(String p_file) {
save_resource_in_path(current_res,p_file);
} break;
case SETTINGS_LAYOUT_SAVE: {
if (p_file.empty())
return;
if (p_file=="Default") {
confirm_error->set_text("Cannot overwrite default layout!");
confirm_error->popup_centered_minsize();
return;
}
Ref<ConfigFile> config;
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
if (err!=OK && err!=ERR_FILE_NOT_FOUND) {
return; //no config
}
_save_docks_to_config(config, p_file);
config->save(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
layout_dialog->hide();
_update_layouts_menu();
} break;
case SETTINGS_LAYOUT_DELETE: {
if (p_file.empty())
return;
if (p_file=="Default") {
confirm_error->set_text("Cannot delete default layout!");
confirm_error->popup_centered_minsize();
return;
}
Ref<ConfigFile> config;
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
if (err!=OK) {
return; //no config
}
if (!config->has_section(p_file)) {
confirm_error->set_text("Layout name not found!");
confirm_error->popup_centered_minsize();
return;
}
// erase
List<String> keys;
config->get_section_keys(p_file, &keys);
for (List<String>::Element *E=keys.front();E;E=E->next()) {
config->set_value(p_file, E->get(), Variant());
}
config->save(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
layout_dialog->hide();
_update_layouts_menu();
} break;
default: { //save scene?
@ -4033,6 +4095,9 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("_dock_move_left",&EditorNode::_dock_move_left);
ObjectTypeDB::bind_method("_dock_move_right",&EditorNode::_dock_move_right);
ObjectTypeDB::bind_method("_layout_menu_option",&EditorNode::_layout_menu_option);
ObjectTypeDB::bind_method("_layout_dialog_action",&EditorNode::_dialog_action);
ObjectTypeDB::bind_method("set_current_scene",&EditorNode::set_current_scene);
ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version);
ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed);
@ -4327,6 +4392,15 @@ void EditorNode::_save_docks() {
Ref<ConfigFile> config;
config.instance();
_save_docks_to_config(config, "docks");
editor_data.get_plugin_window_layout(config);
config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg"));
}
void EditorNode::_save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section) {
for(int i=0;i<DOCK_SLOT_MAX;i++) {
String names;
for(int j=0;j<dock_slot[i]->get_tab_count();j++) {
@ -4337,7 +4411,7 @@ void EditorNode::_save_docks() {
}
if (names!="") {
config->set_value("docks","dock_"+itos(i+1),names);
p_layout->set_value(p_section,"dock_"+itos(i+1),names);
}
}
@ -4351,7 +4425,7 @@ void EditorNode::_save_docks() {
for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
if (splits[i]->is_visible()) {
config->set_value("docks","dock_split_"+itos(i+1),splits[i]->get_split_offset());
p_layout->set_value(p_section,"dock_split_"+itos(i+1),splits[i]->get_split_offset());
}
}
@ -4365,13 +4439,9 @@ void EditorNode::_save_docks() {
for(int i=0;i<4;i++) {
config->set_value("docks","dock_hsplit_"+itos(i+1),h_splits[i]->get_split_offset());
p_layout->set_value(p_section,"dock_hsplit_"+itos(i+1),h_splits[i]->get_split_offset());
}
editor_data.get_plugin_window_layout(config);
config->save(EditorSettings::get_singleton()->get_project_settings_path().plus_file("editor_layout.cfg"));
}
void EditorNode::save_layout() {
@ -4393,12 +4463,19 @@ void EditorNode::_load_docks() {
return; //no config
}
_load_docks_from_config(config, "docks");
editor_data.set_plugin_window_layout(config);
}
void EditorNode::_load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section) {
for(int i=0;i<DOCK_SLOT_MAX;i++) {
if (!config->has_section_key("docks","dock_"+itos(i+1)))
if (!p_layout->has_section_key(p_section,"dock_"+itos(i+1)))
continue;
Vector<String> names = String(config->get_value("docks","dock_"+itos(i+1))).split(",");
Vector<String> names = String(p_layout->get_value(p_section,"dock_"+itos(i+1))).split(",");
for(int j=0;j<names.size();j++) {
@ -4418,7 +4495,7 @@ void EditorNode::_load_docks() {
if (atidx==-1) //well, it's not anywhere
continue;
if (atidx==j) {
if (atidx==i) {
node->raise();
continue;
}
@ -4433,7 +4510,6 @@ void EditorNode::_load_docks() {
dock_slot[i]->add_child(node);
dock_slot[i]->show();
}
}
VSplitContainer*splits[DOCK_SLOT_MAX/2]={
@ -4445,14 +4521,14 @@ void EditorNode::_load_docks() {
for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
if (!config->has_section_key("docks","dock_split_"+itos(i+1)))
if (!p_layout->has_section_key(p_section,"dock_split_"+itos(i+1)))
continue;
int ofs = config->get_value("docks","dock_split_"+itos(i+1));
int ofs = p_layout->get_value(p_section,"dock_split_"+itos(i+1));
splits[i]->set_split_offset(ofs);
}
HSplitContainer *h_splits[4]={
HSplitContainer*h_splits[4]={
left_l_hsplit,
left_r_hsplit,
main_hsplit,
@ -4460,9 +4536,9 @@ void EditorNode::_load_docks() {
};
for(int i=0;i<4;i++) {
if (!config->has_section_key("docks","dock_hsplit_"+itos(i+1)))
if (!p_layout->has_section_key(p_section,"dock_hsplit_"+itos(i+1)))
continue;
int ofs = config->get_value("docks","dock_hsplit_"+itos(i+1));
int ofs = p_layout->get_value(p_section,"dock_hsplit_"+itos(i+1));
h_splits[i]->set_split_offset(ofs);
}
@ -4480,8 +4556,78 @@ void EditorNode::_load_docks() {
dock_slot[i]->set_current_tab(0);
}
}
}
editor_data.set_plugin_window_layout(config);
void EditorNode::_update_layouts_menu() {
editor_layouts->clear();
editor_layouts->set_size(Vector2());
editor_layouts->add_item("Save Layout", SETTINGS_LAYOUT_SAVE);
editor_layouts->add_item("Delete Layout", SETTINGS_LAYOUT_DELETE);
editor_layouts->add_separator();
editor_layouts->add_item("Default", SETTINGS_LAYOUT_DEFAULT);
Ref<ConfigFile> config;
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
if (err!=OK) {
return; //no config
}
List<String> layouts;
config.ptr()->get_sections(&layouts);
for (List<String>::Element *E=layouts.front();E;E=E->next()) {
String layout=E->get();
if (layout!="Default")
editor_layouts->add_item(layout);
}
}
void EditorNode::_layout_menu_option(int p_id) {
switch (p_id) {
case SETTINGS_LAYOUT_SAVE: {
current_option=p_id;
layout_dialog->clear_layout_name();
layout_dialog->set_title("Save Layout");
layout_dialog->get_ok()->set_text("Save");
layout_dialog->popup_centered();
} break;
case SETTINGS_LAYOUT_DELETE: {
current_option=p_id;
layout_dialog->clear_layout_name();
layout_dialog->set_title("Delete Layout");
layout_dialog->get_ok()->set_text("Delete");
layout_dialog->popup_centered();
} break;
case SETTINGS_LAYOUT_DEFAULT: {
_load_docks_from_config(default_theme, "docks");
_save_docks();
} break;
default: {
Ref<ConfigFile> config;
config.instance();
Error err = config->load(EditorSettings::get_singleton()->get_settings_path().plus_file("editor_layouts.cfg"));
if (err!=OK) {
return; //no config
}
int idx=editor_layouts->get_item_index(p_id);
_load_docks_from_config(config, editor_layouts->get_item_text(idx));
_save_docks();
}
}
}
@ -5237,17 +5383,29 @@ EditorNode::EditorNode() {
right_menu_hb->add_child( settings_menu );
p=settings_menu->get_popup();
//p->add_item("Export Settings",SETTINGS_EXPORT_PREFERENCES);
p->add_item("Editor Settings",SETTINGS_PREFERENCES);
//p->add_item("Optimization Presets",SETTINGS_OPTIMIZED_PRESETS);
p->add_separator();
editor_layouts = memnew( PopupMenu );
editor_layouts->set_name("Layouts");
p->add_child(editor_layouts);
editor_layouts->connect("item_pressed",this,"_layout_menu_option");
p->add_submenu_item("Editor Layout", "Layouts");
p->add_separator();
p->add_check_item("Show Animation",SETTINGS_SHOW_ANIMATION,KEY_MASK_CMD+KEY_N);
p->add_separator();
p->add_item("Install Export Templates",SETTINGS_LOAD_EXPORT_TEMPLATES);
p->add_separator();
p->add_item("About",SETTINGS_ABOUT);
layout_dialog = memnew( EditorLayoutDialog );
gui_base->add_child(layout_dialog);
layout_dialog->set_hide_on_ok(false);
layout_dialog->set_size(Size2(175, 70));
confirm_error = memnew( AcceptDialog );
layout_dialog->add_child(confirm_error);
layout_dialog->connect("layout_selected", this,"_layout_dialog_action");
sources_button = memnew( ToolButton );
right_menu_hb->add_child(sources_button);
@ -5434,7 +5592,19 @@ EditorNode::EditorNode() {
scenes_dock->connect("open",this,"open_request");
scenes_dock->connect("instance",this,"_instance_request");
const String docks_section = "docks";
default_theme.instance();
default_theme->set_value(docks_section, "dock_3", "Scene");
default_theme->set_value(docks_section, "dock_4", "FileSystem");
default_theme->set_value(docks_section, "dock_5", "Inspector");
for(int i=0;i<DOCK_SLOT_MAX/2;i++)
default_theme->set_value(docks_section, "dock_hsplit_"+itos(i+1), 0);
for(int i=0;i<DOCK_SLOT_MAX/2;i++)
default_theme->set_value(docks_section, "dock_split_"+itos(i+1), 0);
_update_layouts_menu();
log = memnew( EditorLog );
center_split->add_child(log);
@ -5743,7 +5913,7 @@ EditorNode::EditorNode() {
resource_preview->add_preview_generator( Ref<EditorMeshPreviewPlugin>( memnew(EditorMeshPreviewPlugin )));
circle_step_msec=OS::get_singleton()->get_ticks_msec();
circle_step_frame=OS::get_singleton()->get_frames_drawn();;
circle_step_frame=OS::get_singleton()->get_frames_drawn();
circle_step=0;
_rebuild_import_menu();

View file

@ -76,6 +76,7 @@
#include "editor_reimport_dialog.h"
#include "import_settings.h"
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_layout_dialog.h"
#include "fileserver/editor_file_server.h"
#include "editor_resource_preview.h"
@ -167,6 +168,9 @@ class EditorNode : public Node {
SETTINGS_EXPORT_PREFERENCES,
SETTINGS_PREFERENCES,
SETTINGS_OPTIMIZED_PRESETS,
SETTINGS_LAYOUT_SAVE,
SETTINGS_LAYOUT_DELETE,
SETTINGS_LAYOUT_DEFAULT,
SETTINGS_SHOW_ANIMATION,
SETTINGS_LOAD_EXPORT_TEMPLATES,
SETTINGS_HELP,
@ -284,6 +288,11 @@ class EditorNode : public Node {
AcceptDialog *about;
AcceptDialog *warning;
Ref<ConfigFile> default_theme;
PopupMenu *editor_layouts;
EditorLayoutDialog *layout_dialog;
AcceptDialog *confirm_error;
//OptimizedPresetsDialog *optimized_presets;
EditorSettingsDialog *settings_config_dialog;
RunSettingsDialog *run_settings_dialog;
@ -523,13 +532,18 @@ class EditorNode : public Node {
void _save_docks();
void _load_docks();
void _save_docks_to_config(Ref<ConfigFile> p_layout, const String& p_section);
void _load_docks_from_config(Ref<ConfigFile> p_layout, const String& p_section);
void _update_layouts_menu();
void _layout_menu_option(int p_idx);
void _toggle_search_bar(bool p_pressed);
void _clear_search_box();
protected:
void _notification(int p_what);
static void _bind_methods();
static void _bind_methods();
public:
enum EditorTable {

View file

@ -107,6 +107,7 @@ public:
static EditorSettings *get_singleton();
void erase(String p_var);
String get_settings_path() const;
String get_global_settings_path() const;
String get_project_settings_path() const;
const Map<String,Plugin>& get_plugins() const { return plugins; }

View file

@ -27,151 +27,130 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "groups_editor.h"
#include "scene/gui/box_container.h"
#include "scene/gui/box_container.h"
#include "scene/gui/label.h"
void GroupsEditor::_add_group(const String& p_group) {
#include "print_string.h"
void GroupsEditor::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
connect("confirmed", this,"_close");
}
if (p_what==NOTIFICATION_EXIT_TREE) {
disconnect("confirmed", this,"_close");
}
}
void GroupsEditor::_close() {
hide();
}
void GroupsEditor::_add() {
if (!node)
return;
undo_redo->create_action("Add To Group");
undo_redo->add_do_method(node,"add_to_group",group_name->get_text(),true);
undo_redo->add_undo_method(node,"remove_from_group",group_name->get_text());
String name = group_name->get_text();
if (name.strip_edges()=="")
return;
if (node->is_in_group(name))
return;
undo_redo->create_action("Add to Group");
undo_redo->add_do_method(node,"add_to_group",name,true);
undo_redo->add_do_method(this,"update_tree");
undo_redo->add_undo_method(node,"remove_from_group",name,get_text());
undo_redo->add_undo_method(this,"update_tree");
undo_redo->commit_action();
}
void GroupsEditor::_remove_group(Object *p_item, int p_column, int p_id) {
void GroupsEditor::_remove() {
if (!tree->get_selected())
return;
if (!node)
return;
TreeItem *sel = tree->get_selected();
if (!sel)
TreeItem *ti = p_item->cast_to<TreeItem>();
if (!ti)
return;
node->remove_from_group( sel->get_text(0) );
update_tree();
String name = ti->get_text(0);
undo_redo->create_action("Remove from Group");
undo_redo->add_do_method(node,"remove_from_group",name);
undo_redo->add_do_method(this,"update_tree");
undo_redo->add_undo_method(node,"add_to_group",name,true);
undo_redo->add_undo_method(this,"update_tree");
undo_redo->commit_action();
}
struct _GroupInfoComparator {
bool operator()(const Node::GroupInfo& p_a, const Node::GroupInfo& p_b) const {
return p_a.name.operator String() < p_b.name.operator String();
}
};
void GroupsEditor::update_tree() {
tree->clear();
if (!node)
return;
List<GroupInfo> groups;
node->get_groups(&groups);
TreeItem *root=tree->create_item();
for(List<GroupInfo>::Element *E=groups.front();E;E=E->next()) {
if (!E->get().persistent)
continue;
TreeItem *item=tree->create_item(root);
item->set_text(0, E->get().name);
}
List<Node::GroupInfo> groups;
node->get_groups(&groups);
groups.sort_custom<_GroupInfoComparator>();
TreeItem *root=tree->create_item();
for(List<GroupInfo>::Element *E=groups.front();E;E=E->next()) {
Node::GroupInfo gi = E->get();
if (!gi.persistent)
continue;
TreeItem *item=tree->create_item(root);
item->set_text(0, gi.name);
item->add_button(0, get_icon("Remove", "EditorIcons"), 0);
}
}
void GroupsEditor::set_current(Node* p_node) {
node=p_node;
update_tree();
}
void GroupsEditor::_bind_methods() {
ObjectTypeDB::bind_method("_add",&GroupsEditor::_add);
ObjectTypeDB::bind_method("_close",&GroupsEditor::_close);
ObjectTypeDB::bind_method("_remove",&GroupsEditor::_remove);
ObjectTypeDB::bind_method("_add_group",&GroupsEditor::_add_group);
ObjectTypeDB::bind_method("_remove_group",&GroupsEditor::_remove_group);
ObjectTypeDB::bind_method("update_tree",&GroupsEditor::update_tree);
}
GroupsEditor::GroupsEditor() {
node=NULL;
set_title("Group Editor");
Label * label = memnew( Label );
label->set_pos( Point2( 8,11) );
label->set_text("Groups:");
add_child(label);
group_name = memnew(LineEdit);
group_name->set_anchor( MARGIN_RIGHT, ANCHOR_END );
group_name->set_begin( Point2( 15,28) );
group_name->set_end( Point2( 94,48 ) );
add_child(group_name);
tree = memnew( Tree );
tree->set_anchor( MARGIN_RIGHT, ANCHOR_END );
tree->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
tree->set_begin( Point2( 15,52) );
tree->set_end( Point2( 94,42 ) );
tree->set_hide_root(true);
add_child(tree);
VBoxContainer *vbc = memnew( VBoxContainer );
add_child(vbc);
set_child_rect(vbc);
HBoxContainer *hbc = memnew( HBoxContainer );
vbc->add_margin_child("Group", hbc);
group_name = memnew( LineEdit );
group_name->set_h_size_flags(SIZE_EXPAND_FILL);
hbc->add_child(group_name);
group_name->connect("text_entered",this,"_add_group");
add = memnew( Button );
add->set_anchor( MARGIN_LEFT, ANCHOR_END );
add->set_anchor( MARGIN_RIGHT, ANCHOR_END );
add->set_begin( Point2( 90, 28 ) );
add->set_end( Point2( 15, 48 ) );
add->set_text("Add");
add_child(add);
remove = memnew( Button );
remove->set_anchor( MARGIN_LEFT, ANCHOR_END );
remove->set_anchor( MARGIN_RIGHT, ANCHOR_END );
remove->set_begin( Point2( 90, 52 ) );
remove->set_end( Point2( 15, 72 ) );
remove->set_text("Remove");
add_child(remove);
hbc->add_child(add);
add->connect("pressed", this,"_add_group", varray(String()));
tree = memnew( Tree );
tree->set_hide_root(true);
tree->set_v_size_flags(SIZE_EXPAND_FILL);
vbc->add_margin_child("Node Group(s)", tree, true);
tree->connect("button_pressed",this,"_remove_group");
get_ok()->set_text("Close");
add->connect("pressed", this,"_add");
remove->connect("pressed", this,"_remove");
node=NULL;
}
GroupsEditor::~GroupsEditor()
{
}

View file

@ -29,42 +29,42 @@
#ifndef GROUPS_EDITOR_H
#define GROUPS_EDITOR_H
#include "scene/gui/dialogs.h"
#include "scene/gui/button.h"
#include "scene/gui/tree.h"
#include "scene/gui/line_edit.h"
#include "undo_redo.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
class GroupsEditor : public ConfirmationDialog {
OBJ_TYPE( GroupsEditor, ConfirmationDialog );
LineEdit *group_name;
Tree *tree;
Button *add;
Button *remove;
class GroupsEditor : public AcceptDialog {
OBJ_TYPE(GroupsEditor,AcceptDialog);
Node *node;
LineEdit *group_name;
Button *add;
Tree *tree;
UndoRedo *undo_redo;
void update_tree();
void _add();
void _remove();
void _add_group(const String& p_group="");
void _remove_group(Object *p_item, int p_column, int p_id);
void _close();
protected:
void _notification(int p_what);
static void _bind_methods();
static void _bind_methods();
public:
void set_undo_redo(UndoRedo *p_undoredo) { undo_redo=p_undoredo; }
void set_current(Node* p_node);
GroupsEditor();
~GroupsEditor();
};
#endif

View file

@ -30,7 +30,6 @@
#include "io/resource_loader.h"
bool ItemListPlugin::_set(const StringName& p_name, const Variant& p_value) {
String name = p_name;
@ -45,12 +44,10 @@ bool ItemListPlugin::_set(const StringName& p_name, const Variant& p_value) {
set_item_checkable(idx,p_value);
else if (what=="checked")
set_item_checked(idx,p_value);
else if (what=="enabled")
set_item_enabled(idx,p_value);
else if (what=="accel")
set_item_accel(idx,p_value);
else if (what=="id")
set_item_id(idx,p_value);
else if (what=="enabled")
set_item_enabled(idx,p_value);
else if (what=="separator")
set_item_separator(idx,p_value);
else
@ -60,6 +57,7 @@ bool ItemListPlugin::_set(const StringName& p_name, const Variant& p_value) {
}
bool ItemListPlugin::_get(const StringName& p_name,Variant &r_ret) const {
String name = p_name;
int idx = name.get_slice("/",0).to_int();
String what=name.get_slice("/",1);
@ -72,12 +70,10 @@ bool ItemListPlugin::_get(const StringName& p_name,Variant &r_ret) const {
r_ret=is_item_checkable(idx);
else if (what=="checked")
r_ret=is_item_checked(idx);
else if (what=="enabled")
r_ret=is_item_enabled(idx);
else if (what=="accel")
r_ret=get_item_accel(idx);
else if (what=="id")
r_ret=get_item_id(idx);
else if (what=="enabled")
r_ret=is_item_enabled(idx);
else if (what=="separator")
r_ret=is_item_separator(idx);
else
@ -93,35 +89,112 @@ void ItemListPlugin::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo(Variant::STRING,base+"text") );
p_list->push_back( PropertyInfo(Variant::OBJECT,base+"icon",PROPERTY_HINT_RESOURCE_TYPE,"Texture") );
if (get_flags()&FLAG_CHECKABLE) {
int flags = get_flags();
if (flags&FLAG_CHECKABLE) {
p_list->push_back( PropertyInfo(Variant::BOOL,base+"checkable") );
p_list->push_back( PropertyInfo(Variant::BOOL,base+"checked") );
}
if (get_flags()&FLAG_ENABLE) {
p_list->push_back( PropertyInfo(Variant::BOOL,base+"enabled") );
}
if (get_flags()&FLAG_ACCEL) {
p_list->push_back( PropertyInfo(Variant::INT,base+"accel",PROPERTY_HINT_KEY_ACCEL) );
}
if (get_flags()&FLAG_ID) {
if (flags&FLAG_ID)
p_list->push_back( PropertyInfo(Variant::INT,base+"id",PROPERTY_HINT_RANGE,"-1,4096") );
}
if (get_flags()&FLAG_SEPARATOR) {
if (flags&FLAG_ENABLE)
p_list->push_back( PropertyInfo(Variant::BOOL,base+"enabled") );
if (flags&FLAG_SEPARATOR)
p_list->push_back( PropertyInfo(Variant::BOOL,base+"separator") );
}
}
}
///////////////////////////////////////////////////////////////
///////////////////////// PLUGINS /////////////////////////////
///////////////////////////////////////////////////////////////
void ItemListOptionButtonPlugin::set_object(Object *p_object) {
ob = p_object->cast_to<OptionButton>();
}
bool ItemListOptionButtonPlugin::handles(Object *p_object) const {
return p_object->is_type("OptionButton");
}
int ItemListOptionButtonPlugin::get_flags() const {
return FLAG_ICON|FLAG_ID|FLAG_ENABLE;
}
void ItemListOptionButtonPlugin::add_item() {
ob->add_item( "Item "+itos(ob->get_item_count()));
_change_notify();
}
int ItemListOptionButtonPlugin::get_item_count() const {
return ob->get_item_count();
}
void ItemListOptionButtonPlugin::erase(int p_idx) {
ob->remove_item(p_idx);
_change_notify();
}
ItemListOptionButtonPlugin::ItemListOptionButtonPlugin() {
ob=NULL;
}
///////////////////////////////////////////////////////////////
void ItemListPopupMenuPlugin::set_object(Object *p_object) {
if (p_object->is_type("MenuButton"))
pp = p_object->cast_to<MenuButton>()->get_popup();
else
pp = p_object->cast_to<PopupMenu>();
}
bool ItemListPopupMenuPlugin::handles(Object *p_object) const {
return p_object->is_type("PopupMenu") || p_object->is_type("MenuButton");
}
int ItemListPopupMenuPlugin::get_flags() const {
return FLAG_ICON|FLAG_CHECKABLE|FLAG_ID|FLAG_ENABLE|FLAG_SEPARATOR;
}
void ItemListPopupMenuPlugin::add_item() {
pp->add_item( "Item "+itos(pp->get_item_count()));
_change_notify();
}
int ItemListPopupMenuPlugin::get_item_count() const {
return pp->get_item_count();
}
void ItemListPopupMenuPlugin::erase(int p_idx) {
pp->remove_item(p_idx);
_change_notify();
}
ItemListPopupMenuPlugin::ItemListPopupMenuPlugin() {
pp=NULL;
}
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////
void ItemListEditor::_node_removed(Node *p_node) {
if(p_node==item_list) {
@ -129,30 +202,6 @@ void ItemListEditor::_node_removed(Node *p_node) {
hide();
dialog->hide();
}
}
void ItemListEditor::_delete_pressed() {
String p = prop_editor->get_selected_path();
if (p.find("/")!=-1) {
if (selected_idx<0 || selected_idx>=item_plugins.size())
return;
item_plugins[selected_idx]->erase(p.get_slice("/",0).to_int());;
}
}
void ItemListEditor::_add_pressed() {
if (selected_idx<0 || selected_idx>=item_plugins.size())
return;
item_plugins[selected_idx]->add_item();
}
void ItemListEditor::_notification(int p_notification) {
@ -160,57 +209,73 @@ void ItemListEditor::_notification(int p_notification) {
if (p_notification==NOTIFICATION_ENTER_TREE) {
add_button->set_icon(get_icon("Add","EditorIcons"));
del_button->set_icon(get_icon("Del","EditorIcons"));
del_button->set_icon(get_icon("Remove","EditorIcons"));
}
}
void ItemListEditor::_add_pressed() {
void ItemListEditor::_menu_option(int p_option) {
if (selected_idx==-1)
return;
switch(p_option) {
case MENU_EDIT_ITEMS: {
dialog->popup_centered_ratio();
} break;
}
item_plugins[selected_idx]->add_item();
}
void ItemListEditor::_delete_pressed() {
TreeItem *ti = tree->get_selected();
if (!ti)
return;
if (ti->get_parent()!=tree->get_root())
return;
int idx = ti->get_text(0).to_int();
if (selected_idx==-1)
return;
item_plugins[selected_idx]->erase(idx);
}
void ItemListEditor::_edit_items() {
dialog->popup_centered(Vector2(300, 400));
}
void ItemListEditor::edit(Node *p_item_list) {
item_list=p_item_list;
if (!item_list) {
selected_idx=-1;
property_editor->edit(NULL);
return;
}
for(int i=0;i<item_plugins.size();i++) {
if (item_plugins[i]->handles(p_item_list)) {
item_plugins[i]->set_object(p_item_list);
prop_editor->edit(item_plugins[i]);
property_editor->edit(item_plugins[i]);
if (has_icon(item_list->get_type(), "EditorIcons"))
toolbar_button->set_icon(get_icon(item_list->get_type(), "EditorIcons"));
else
toolbar_button->set_icon(Ref<Texture>());
selected_idx=i;
return;
}
}
selected_idx=-1;
prop_editor->edit(NULL);
}
void ItemListEditor::_bind_methods() {
ObjectTypeDB::bind_method("_menu_option",&ItemListEditor::_menu_option);
ObjectTypeDB::bind_method("_add_button",&ItemListEditor::_add_pressed);
ObjectTypeDB::bind_method("_delete_button",&ItemListEditor::_delete_pressed);
//ObjectTypeDB::bind_method("_populate",&ItemListEditor::_populate);
property_editor->edit(NULL);
}
bool ItemListEditor::handles(Object *p_object) const {
return false;
for(int i=0;i<item_plugins.size();i++) {
if (item_plugins[i]->handles(p_object)) {
return true;
@ -218,56 +283,64 @@ bool ItemListEditor::handles(Object *p_object) const {
}
return false;
}
void ItemListEditor::_bind_methods() {
ObjectTypeDB::bind_method("_edit_items",&ItemListEditor::_edit_items);
ObjectTypeDB::bind_method("_add_button",&ItemListEditor::_add_pressed);
ObjectTypeDB::bind_method("_delete_button",&ItemListEditor::_delete_pressed);
}
ItemListEditor::ItemListEditor() {
selected_idx=-1;
options = memnew( MenuButton );
add_child(options);
options->set_area_as_parent_rect();
options->set_text("Items");
options->get_popup()->add_item("Edit Items",MENU_EDIT_ITEMS);
//options->get_popup()->add_item("Clear",MENU_CLEAR);
add_child( memnew( VSeparator ) );
options->get_popup()->connect("item_pressed", this,"_menu_option");
toolbar_button = memnew( ToolButton );
toolbar_button->set_text("Items");
add_child(toolbar_button);
toolbar_button->connect("pressed",this,"_edit_items");
dialog = memnew( AcceptDialog );
dialog->set_title("Item List Editor");
add_child( dialog );
VBoxContainer *vbc = memnew( VBoxContainer );
dialog->add_child(vbc);
dialog->set_child_rect(vbc);
HBoxContainer *hbc = memnew( HBoxContainer );
dialog->add_child(hbc);
dialog->set_child_rect(hbc);
prop_editor = memnew( PropertyEditor );
hbc->add_child(prop_editor);
prop_editor->set_h_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *vbc = memnew( VBoxContainer );
hbc->add_child(vbc);
hbc->set_h_size_flags(SIZE_EXPAND_FILL);
vbc->add_child(hbc);
add_button = memnew( Button );
//add_button->set_text("Add");
add_button->set_text("Add");
hbc->add_child(add_button);
add_button->connect("pressed",this,"_add_button");
vbc->add_child(add_button);
hbc->add_spacer();
del_button = memnew( Button );
//del_button->set_text("Del");
del_button->set_text("Delete");
hbc->add_child(del_button);
del_button->connect("pressed",this,"_delete_button");
vbc->add_child(del_button);
dialog->set_title("Item List");
prop_editor->hide_top_label();
property_editor = memnew( PropertyEditor );
property_editor->hide_top_label();
property_editor->set_subsection_selectable(true);
vbc->add_child(property_editor);
property_editor->set_v_size_flags(SIZE_EXPAND_FILL);
tree = property_editor->get_scene_tree();
}
ItemListEditor::~ItemListEditor() {
for(int i=0;i<item_plugins.size();i++)
memdelete( item_plugins[i] );
}
void ItemListEditorPlugin::edit(Object *p_object) {
@ -288,127 +361,19 @@ void ItemListEditorPlugin::make_visible(bool p_visible) {
item_list_editor->hide();
item_list_editor->edit(NULL);
}
}
ItemListEditor::~ItemListEditor() {
for(int i=0;i<item_plugins.size();i++)
memdelete( item_plugins[i] );
}
///////////////////////// PLUGINS /////////////////////////////
///////////////////////// PLUGINS /////////////////////////////
///////////////////////// PLUGINS /////////////////////////////
///////////////////////// PLUGINS /////////////////////////////
///////////////////////// PLUGINS /////////////////////////////
class ItemListOptionButtonPlugin : public ItemListPlugin {
OBJ_TYPE(ItemListOptionButtonPlugin,ItemListPlugin);
OptionButton *ob;
public:
virtual void set_object(Object *p_object) { ob = p_object->cast_to<OptionButton>(); }
virtual bool handles(Object *p_object) const { return p_object->cast_to<OptionButton>()!=NULL; }
virtual int get_flags() const { return FLAG_ICON|FLAG_ID|FLAG_ENABLE; }
virtual void set_item_text(int p_idx,const String& p_text){ ob->set_item_text(p_idx,p_text);}
virtual void set_item_icon(int p_idx,const Ref<Texture>& p_tex){ ob->set_item_icon(p_idx,p_tex);}
virtual void set_item_enabled(int p_idx,int p_enabled){ ob->set_item_disabled(p_idx,!p_enabled);}
virtual void set_item_id(int p_idx,int p_id){ ob->set_item_ID(p_idx,p_id);}
virtual String get_item_text(int p_idx) const{ return ob->get_item_text(p_idx); };
virtual Ref<Texture> get_item_icon(int p_idx) const{ return ob->get_item_icon(p_idx); };
virtual bool is_item_enabled(int p_idx) const{ return !ob->is_item_disabled(p_idx); };
virtual int get_item_id(int p_idx) const{ return ob->get_item_ID(p_idx); };
virtual void add_item() { ob->add_item( "New Item "+itos(ob->get_item_count())); _change_notify();}
virtual int get_item_count() const { return ob->get_item_count(); }
virtual void erase(int p_idx) { ob->remove_item(p_idx); _change_notify();}
ItemListOptionButtonPlugin() { ob=NULL; }
};
class ItemListPopupMenuPlugin : public ItemListPlugin {
OBJ_TYPE(ItemListPopupMenuPlugin,ItemListPlugin);
PopupMenu *pp;
public:
virtual void set_object(Object *p_object) {
if (p_object->cast_to<MenuButton>())
pp = p_object->cast_to<MenuButton>()->get_popup();
else
pp = p_object->cast_to<PopupMenu>();
}
virtual bool handles(Object *p_object) const { return p_object->cast_to<PopupMenu>()!=NULL || p_object->cast_to<MenuButton>()!=NULL; }
virtual int get_flags() const { return FLAG_ICON|FLAG_ID|FLAG_ENABLE|FLAG_CHECKABLE|FLAG_SEPARATOR|FLAG_ACCEL; }
virtual void set_item_text(int p_idx,const String& p_text){ pp->set_item_text(p_idx,p_text); }
virtual void set_item_icon(int p_idx,const Ref<Texture>& p_tex){ pp->set_item_icon(p_idx,p_tex);}
virtual void set_item_checkable(int p_idx,bool p_check){ pp->set_item_as_checkable(p_idx,p_check);}
virtual void set_item_checked(int p_idx,bool p_checked){ pp->set_item_checked(p_idx,p_checked);}
virtual void set_item_accel(int p_idx,int p_accel){ pp->set_item_accelerator(p_idx,p_accel);}
virtual void set_item_enabled(int p_idx,int p_enabled){ pp->set_item_disabled(p_idx,!p_enabled);}
virtual void set_item_id(int p_idx,int p_id){ pp->set_item_ID(p_idx,p_idx);}
virtual void set_item_separator(int p_idx,bool p_separator){ pp->set_item_as_separator(p_idx,p_separator);}
virtual String get_item_text(int p_idx) const{ return pp->get_item_text(p_idx); };
virtual Ref<Texture> get_item_icon(int p_idx) const{ return pp->get_item_icon(p_idx); };
virtual bool is_item_checkable(int p_idx) const{ return pp->is_item_checkable(p_idx); };
virtual bool is_item_checked(int p_idx) const{ return pp->is_item_checked(p_idx); };
virtual int get_item_accel(int p_idx) const{ return pp->get_item_accelerator(p_idx); };
virtual bool is_item_enabled(int p_idx) const{ return !pp->is_item_disabled(p_idx); };
virtual int get_item_id(int p_idx) const{ return pp->get_item_ID(p_idx); };
virtual bool is_item_separator(int p_idx) const{ return pp->is_item_separator(p_idx); };
virtual void add_item() { pp->add_item( "New Item "+itos(pp->get_item_count())); _change_notify();}
virtual int get_item_count() const { return pp->get_item_count(); }
virtual void erase(int p_idx) { pp->remove_item(p_idx); _change_notify();}
ItemListPopupMenuPlugin() { pp=NULL; }
};
ItemListEditorPlugin::ItemListEditorPlugin(EditorNode *p_node) {
editor=p_node;
item_list_editor = memnew( ItemListEditor );
editor->get_viewport()->add_child(item_list_editor);
// item_list_editor->set_anchor(MARGIN_LEFT,Control::ANCHOR_END);
// item_list_editor->set_anchor(MARGIN_RIGHT,Control::ANCHOR_END);
item_list_editor->set_margin(MARGIN_LEFT,180);
item_list_editor->set_margin(MARGIN_RIGHT,230);
item_list_editor->set_margin(MARGIN_TOP,0);
item_list_editor->set_margin(MARGIN_BOTTOM,10);
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(item_list_editor);
item_list_editor->hide();
item_list_editor->add_plugin( memnew( ItemListOptionButtonPlugin) );
item_list_editor->add_plugin( memnew( ItemListPopupMenuPlugin) );
item_list_editor->add_plugin( memnew( ItemListOptionButtonPlugin ) );
item_list_editor->add_plugin( memnew( ItemListPopupMenuPlugin ) );
}
ItemListEditorPlugin::~ItemListEditorPlugin()
{
}

View file

@ -31,10 +31,11 @@
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
#include "canvas_item_editor_plugin.h"
#include "scene/gui/option_button.h"
#include "scene/gui/menu_button.h"
#include "scene/gui/popup_menu.h"
#include "scene/gui/spin_box.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
@ -51,43 +52,42 @@ protected:
bool _get(const StringName& p_name,Variant &r_ret) const;
void _get_property_list( List<PropertyInfo> *p_list) const;
public:
enum Flags {
FLAG_ICON=1,
FLAG_CHECKABLE=2,
FLAG_ACCEL=4,
FLAG_ID=8,
FLAG_ENABLE=16,
FLAG_SEPARATOR=32
FLAG_ID=4,
FLAG_ENABLE=8,
FLAG_SEPARATOR=16
};
virtual void set_object(Object *p_object)=0;
virtual bool handles(Object *p_object) const=0;
virtual int get_flags() const=0;
virtual void set_item_text(int p_idx,const String& p_text){}
virtual void set_item_icon(int p_idx,const Ref<Texture>& p_tex){}
virtual void set_item_checkable(int p_idx,bool p_check){}
virtual void set_item_checked(int p_idx,bool p_checked){}
virtual void set_item_accel(int p_idx,int p_accel){}
virtual void set_item_enabled(int p_idx,int p_enabled){}
virtual void set_item_id(int p_idx,int p_id){}
virtual void set_item_separator(int p_idx,bool p_separator){}
virtual void set_item_text(int p_idx, const String& p_text) {}
virtual String get_item_text(int p_idx) const{ return ""; };
virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) {}
virtual Ref<Texture> get_item_icon(int p_idx) const{ return Ref<Texture>(); };
virtual void set_item_checkable(int p_idx, bool p_check) {}
virtual bool is_item_checkable(int p_idx) const{ return false; };
virtual void set_item_checked(int p_idx, bool p_checked) {}
virtual bool is_item_checked(int p_idx) const{ return false; };
virtual int get_item_accel(int p_idx) const{ return 0; };
virtual void set_item_enabled(int p_idx, int p_enabled) {}
virtual bool is_item_enabled(int p_idx) const{ return false; };
virtual void set_item_id(int p_idx, int p_id) {}
virtual int get_item_id(int p_idx) const{ return -1; };
virtual bool is_item_separator(int p_idx) const{ return false; };
virtual void set_item_separator(int p_idx, bool p_separator) {}
virtual bool is_item_separator(int p_idx) const { return false; };
virtual void add_item()=0;
virtual int get_item_count() const=0;
@ -96,41 +96,107 @@ public:
ItemListPlugin() {}
};
class ItemListEditor : public Control {
///////////////////////////////////////////////////////////////
OBJ_TYPE(ItemListEditor, Control );
class ItemListOptionButtonPlugin : public ItemListPlugin {
OBJ_TYPE(ItemListOptionButtonPlugin,ItemListPlugin);
OptionButton *ob;
public:
virtual void set_object(Object *p_object);
virtual bool handles(Object *p_object) const;
virtual int get_flags() const;
virtual void set_item_text(int p_idx, const String& p_text) { ob->set_item_text(p_idx,p_text); }
virtual String get_item_text(int p_idx) const { return ob->get_item_text(p_idx); }
virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { ob->set_item_icon(p_idx, p_tex); }
virtual Ref<Texture> get_item_icon(int p_idx) const { return ob->get_item_icon(p_idx); }
virtual void set_item_enabled(int p_idx, int p_enabled) { ob->set_item_disabled(p_idx, !p_enabled); }
virtual bool is_item_enabled(int p_idx) const { return !ob->is_item_disabled(p_idx); }
virtual void set_item_id(int p_idx, int p_id) { ob->set_item_ID(p_idx,p_id); }
virtual int get_item_id(int p_idx) const { return ob->get_item_ID(p_idx); }
virtual void add_item();
virtual int get_item_count() const;
virtual void erase(int p_idx);
ItemListOptionButtonPlugin();
};
class ItemListPopupMenuPlugin : public ItemListPlugin {
OBJ_TYPE(ItemListPopupMenuPlugin,ItemListPlugin);
PopupMenu *pp;
public:
virtual void set_object(Object *p_object);
virtual bool handles(Object *p_object) const;
virtual int get_flags() const;
virtual void set_item_text(int p_idx, const String& p_text) { pp->set_item_text(p_idx,p_text); }
virtual String get_item_text(int p_idx) const { return pp->get_item_text(p_idx); }
virtual void set_item_icon(int p_idx, const Ref<Texture>& p_tex) { pp->set_item_icon(p_idx,p_tex); }
virtual Ref<Texture> get_item_icon(int p_idx) const { return pp->get_item_icon(p_idx); }
virtual void set_item_checkable(int p_idx, bool p_check) { pp->set_item_as_checkable(p_idx,p_check); }
virtual bool is_item_checkable(int p_idx) const { return pp->is_item_checkable(p_idx); }
virtual void set_item_checked(int p_idx, bool p_checked) { pp->set_item_checked(p_idx,p_checked); }
virtual bool is_item_checked(int p_idx) const { return pp->is_item_checked(p_idx); }
virtual void set_item_enabled(int p_idx, int p_enabled) { pp->set_item_disabled(p_idx,!p_enabled); }
virtual bool is_item_enabled(int p_idx) const { return !pp->is_item_disabled(p_idx); }
virtual void set_item_id(int p_idx, int p_id) { pp->set_item_ID(p_idx,p_idx); }
virtual int get_item_id(int p_idx) const { return pp->get_item_ID(p_idx); }
virtual void set_item_separator(int p_idx, bool p_separator) { pp->set_item_as_separator(p_idx,p_separator); }
virtual bool is_item_separator(int p_idx) const { return pp->is_item_separator(p_idx); }
virtual void add_item();
virtual int get_item_count() const;
virtual void erase(int p_idx);
ItemListPopupMenuPlugin();
};
///////////////////////////////////////////////////////////////
class ItemListEditor : public HBoxContainer {
OBJ_TYPE(ItemListEditor,HBoxContainer);
Node *item_list;
enum {
MENU_EDIT_ITEMS,
MENU_CLEAR
};
ToolButton *toolbar_button;
AcceptDialog *dialog;
PropertyEditor *prop_editor;
MenuButton * options;
int selected_idx;
PropertyEditor *property_editor;
Tree *tree;
Button *add_button;
Button *del_button;
// FileDialog *emission_file_dialog;
void _menu_option(int);
int selected_idx;
Vector<ItemListPlugin*> item_plugins;
void _node_removed(Node *p_node);
void _edit_items();
void _add_pressed();
void _delete_pressed();
void _node_removed(Node *p_node);
protected:
void _notification(int p_notification);
static void _bind_methods();
public:
@ -143,7 +209,7 @@ public:
class ItemListEditorPlugin : public EditorPlugin {
OBJ_TYPE( ItemListEditorPlugin, EditorPlugin );
OBJ_TYPE(ItemListEditorPlugin,EditorPlugin);
ItemListEditor *item_list_editor;
EditorNode *editor;

View file

@ -2207,9 +2207,9 @@ TreeItem *PropertyEditor::get_parent_node(String p_path,HashMap<String,TreeItem*
}
item->set_editable(0,false);
item->set_selectable(0,false);
item->set_selectable(0,subsection_selectable);
item->set_editable(1,false);
item->set_selectable(1,false);
item->set_selectable(1,subsection_selectable);
if (item->get_parent()==root) {
@ -3511,7 +3511,15 @@ void PropertyEditor::register_text_enter(Node* p_line_edit) {
if (search_box)
search_box->connect("text_changed",this,"_filter_changed");
}
void PropertyEditor::set_subsection_selectable(bool p_selectable) {
if (p_selectable==subsection_selectable)
return;
subsection_selectable=p_selectable;
update_tree();
}
PropertyEditor::PropertyEditor() {
@ -3573,8 +3581,8 @@ PropertyEditor::PropertyEditor() {
show_categories=false;
refresh_countdown=0;
use_doc_hints=false;
use_filter=false;
subsection_selectable=false;
}

View file

@ -163,8 +163,8 @@ class PropertyEditor : public Control {
bool show_categories;
float refresh_countdown;
bool use_doc_hints;
bool use_filter;
bool subsection_selectable;
HashMap<String,String> pending;
String selected_property;
@ -239,6 +239,8 @@ public:
void set_use_filter(bool p_use);
void register_text_enter(Node *p_line_edit);
void set_subsection_selectable(bool p_selectable);
PropertyEditor();
~PropertyEditor();