mirror of
https://github.com/godotengine/godot.git
synced 2025-01-09 03:27:15 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e0e54ea7d4
10
.editorconfig
Normal file
10
.editorconfig
Normal file
@ -0,0 +1,10 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = tab
|
||||
|
||||
[.travis.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -281,3 +281,5 @@ cscope.out
|
||||
cscope.in.out
|
||||
cscope.po.out
|
||||
godot.creator.*
|
||||
|
||||
projects/
|
@ -360,6 +360,11 @@ if selected_platform in platform_list:
|
||||
AddToVSProject(env.scene_sources)
|
||||
AddToVSProject(env.servers_sources)
|
||||
AddToVSProject(env.tool_sources)
|
||||
|
||||
#env['MSVS_VERSION']='9.0'
|
||||
env['MSVSBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
env['MSVSREBUILDCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
env['MSVSCLEANCOM'] = "scons platform=" + selected_platform + " target=" + env["target"] + " bits=" + env["bits"] + " tools=yes"
|
||||
|
||||
debug_variants = ['Debug|Win32']+['Debug|x64']
|
||||
release_variants = ['Release|Win32']+['Release|x64']
|
||||
|
@ -663,14 +663,18 @@ Error ResourceInteractiveLoaderBinary::poll(){
|
||||
|
||||
//maybe it is loaded already
|
||||
String path;
|
||||
int subindex=0;
|
||||
|
||||
|
||||
|
||||
if (!main) {
|
||||
|
||||
path=internal_resources[s].path;
|
||||
if (path.begins_with("local://"))
|
||||
path=path.replace("local://",res_path+"::");
|
||||
if (path.begins_with("local://")) {
|
||||
path=path.replace_first("local://","");
|
||||
subindex = path.to_int();
|
||||
path=res_path+"::"+path;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -709,6 +713,7 @@ Error ResourceInteractiveLoaderBinary::poll(){
|
||||
RES res = RES( r );
|
||||
|
||||
r->set_path(path);
|
||||
r->set_subindex(subindex);
|
||||
|
||||
int pc = f->get_32();
|
||||
|
||||
@ -1434,14 +1439,14 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property,
|
||||
save_unicode_string(path);
|
||||
} else {
|
||||
|
||||
if (!resource_map.has(res)) {
|
||||
if (!resource_set.has(res)) {
|
||||
f->store_32(OBJECT_EMPTY);
|
||||
ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
|
||||
ERR_FAIL();
|
||||
}
|
||||
|
||||
f->store_32(OBJECT_INTERNAL_RESOURCE);
|
||||
f->store_32(resource_map[res]);
|
||||
f->store_32(res->get_subindex());
|
||||
//internal resource
|
||||
}
|
||||
|
||||
@ -1598,7 +1603,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant
|
||||
}
|
||||
|
||||
|
||||
if (resource_map.has(res))
|
||||
if (resource_set.has(res))
|
||||
return;
|
||||
|
||||
List<PropertyInfo> property_list;
|
||||
@ -1613,7 +1618,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant& p_variant
|
||||
}
|
||||
}
|
||||
|
||||
resource_map[ res ] = saved_resources.size();
|
||||
resource_set.insert(res);
|
||||
saved_resources.push_back(res);
|
||||
|
||||
} break;
|
||||
@ -1846,11 +1851,42 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
||||
// save internal resource table
|
||||
f->store_32(saved_resources.size()); //amount of internal resources
|
||||
Vector<uint64_t> ofs_pos;
|
||||
Set<int> used_indices;
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES r = E->get();
|
||||
if (r->get_path()=="" || r->get_path().find("::")!=-1) {
|
||||
save_unicode_string("local://"+itos(ofs_pos.size()));
|
||||
|
||||
if (r->get_subindex()!=0) {
|
||||
if (used_indices.has(r->get_subindex())) {
|
||||
r->set_subindex(0); //repeated
|
||||
} else {
|
||||
used_indices.insert(r->get_subindex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
|
||||
RES r = E->get();
|
||||
if (r->get_path()=="" || r->get_path().find("::")!=-1) {
|
||||
if (r->get_subindex()==0) {
|
||||
int new_subindex=1;
|
||||
if (used_indices.size()) {
|
||||
new_subindex=used_indices.back()->get()+1;
|
||||
}
|
||||
|
||||
r->set_subindex(new_subindex);
|
||||
used_indices.insert(new_subindex);
|
||||
|
||||
}
|
||||
|
||||
save_unicode_string("local://"+itos(r->get_subindex()));
|
||||
if (takeover_paths) {
|
||||
r->set_path(p_path+"::"+itos(ofs_pos.size()),true);
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ class ResourceFormatSaverBinaryInstance {
|
||||
int bin_meta_idx;
|
||||
FileAccess *f;
|
||||
String magic;
|
||||
Map<RES,int> resource_map;
|
||||
Set<RES> resource_set;
|
||||
Map<StringName,int> string_map;
|
||||
Vector<StringName> strings;
|
||||
|
||||
|
@ -1466,6 +1466,7 @@ Error ResourceInteractiveLoaderXML::poll() {
|
||||
|
||||
String type;
|
||||
String path;
|
||||
int subres=0;
|
||||
|
||||
if (!main) {
|
||||
//loading resource
|
||||
@ -1476,11 +1477,15 @@ Error ResourceInteractiveLoaderXML::poll() {
|
||||
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <resource> missing 'type' field.");
|
||||
ERR_FAIL_COND_V(!tag->args.has("type"),ERR_FILE_CORRUPT);
|
||||
path=tag->args["path"];
|
||||
|
||||
error=OK;
|
||||
|
||||
if (path.begins_with("local://")) {
|
||||
//built-in resource (but really external)
|
||||
path=path.replace("local://",local_path+"::");
|
||||
|
||||
path=path.replace("local://","");
|
||||
subres=path.to_int();
|
||||
path=local_path+"::"+path;
|
||||
}
|
||||
|
||||
|
||||
@ -1519,6 +1524,7 @@ Error ResourceInteractiveLoaderXML::poll() {
|
||||
res = RES( r );
|
||||
if (path!="")
|
||||
r->set_path(path);
|
||||
r->set_subindex(subres);
|
||||
|
||||
//load properties
|
||||
|
||||
@ -2029,9 +2035,9 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V
|
||||
|
||||
//internal resource
|
||||
ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?");
|
||||
ERR_FAIL_COND(!resource_map.has(res));
|
||||
ERR_FAIL_COND(!resource_set.has(res));
|
||||
|
||||
params+=" path=\"local://"+itos(resource_map[res])+"\"";
|
||||
params+=" path=\"local://"+itos(res->get_subindex())+"\"";
|
||||
}
|
||||
|
||||
} break;
|
||||
@ -2443,7 +2449,7 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo
|
||||
return;
|
||||
}
|
||||
|
||||
if (resource_map.has(res))
|
||||
if (resource_set.has(res))
|
||||
return;
|
||||
|
||||
List<PropertyInfo> property_list;
|
||||
@ -2466,7 +2472,7 @@ void ResourceFormatSaverXMLInstance::_find_resources(const Variant& p_variant,bo
|
||||
I=I->next();
|
||||
}
|
||||
|
||||
resource_map[ res ] = resource_map.size(); //saved after, so the childs it needs are available when loaded
|
||||
resource_set.insert( res ); //saved after, so the childs it needs are available when loaded
|
||||
saved_resources.push_back(res);
|
||||
|
||||
} break;
|
||||
@ -2537,12 +2543,27 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
|
||||
write_string("\n",false);
|
||||
}
|
||||
|
||||
|
||||
Set<int> used_indices;
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES res = E->get();
|
||||
ERR_CONTINUE(!resource_map.has(res));
|
||||
if (E->next() && (res->get_path()=="" || res->get_path().find("::") != -1 )) {
|
||||
|
||||
if (res->get_subindex()!=0) {
|
||||
if (used_indices.has(res->get_subindex())) {
|
||||
res->set_subindex(0); //repeated
|
||||
} else {
|
||||
used_indices.insert(res->get_subindex());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(List<RES>::Element *E=saved_resources.front();E;E=E->next()) {
|
||||
|
||||
RES res = E->get();
|
||||
ERR_CONTINUE(!resource_set.has(res));
|
||||
bool main = (E->next()==NULL);
|
||||
|
||||
write_tabs();
|
||||
@ -2552,7 +2573,18 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
|
||||
else if (res->get_path().length() && res->get_path().find("::") == -1 )
|
||||
enter_tag("resource","type=\""+res->get_type()+"\" path=\""+res->get_path()+"\""); //bundled
|
||||
else {
|
||||
int idx = resource_map[res];
|
||||
|
||||
if (res->get_subindex()==0) {
|
||||
int new_subindex=1;
|
||||
if (used_indices.size()) {
|
||||
new_subindex=used_indices.back()->get()+1;
|
||||
}
|
||||
|
||||
res->set_subindex(new_subindex);
|
||||
used_indices.insert(new_subindex);
|
||||
}
|
||||
|
||||
int idx = res->get_subindex();
|
||||
enter_tag("resource","type=\""+res->get_type()+"\" path=\"local://"+itos(idx)+"\"");
|
||||
if (takeover_paths) {
|
||||
res->set_path(p_path+"::"+itos(idx),true);
|
||||
|
@ -123,7 +123,7 @@ class ResourceFormatSaverXMLInstance {
|
||||
bool skip_editor;
|
||||
FileAccess *f;
|
||||
int depth;
|
||||
Map<RES,int> resource_map;
|
||||
Set<RES> resource_set;
|
||||
List<RES> saved_resources;
|
||||
List<RES> external_resources;
|
||||
|
||||
|
@ -622,9 +622,39 @@ float Matrix32::basis_determinant() const {
|
||||
}
|
||||
|
||||
Matrix32 Matrix32::interpolate_with(const Matrix32& p_transform, float p_c) const {
|
||||
|
||||
//extract parameters
|
||||
Vector2 p1 = get_origin();
|
||||
Vector2 p2 = p_transform.get_origin();
|
||||
|
||||
real_t r1 = get_rotation();
|
||||
real_t r2 = p_transform.get_rotation();
|
||||
|
||||
Vector2 s1 = get_scale();
|
||||
Vector2 s2 = p_transform.get_scale();
|
||||
|
||||
//slerp rotation
|
||||
Vector2 v1(Math::cos(r1), Math::sin(r1));
|
||||
Vector2 v2(Math::cos(r2), Math::sin(r2));
|
||||
|
||||
real_t dot = v1.dot(v2);
|
||||
|
||||
dot = (dot < -1.0) ? -1.0 : ((dot > 1.0) ? 1.0 : dot); //clamp dot to [-1,1]
|
||||
|
||||
Vector2 v;
|
||||
|
||||
|
||||
return Matrix32();
|
||||
if (dot > 0.9995) {
|
||||
v = Vector2::linear_interpolate(v1, v2, p_c).normalized(); //linearly interpolate to avoid numerical precision issues
|
||||
} else {
|
||||
real_t angle = p_c*Math::acos(dot);
|
||||
Vector2 v3 = (v2 - v1*dot).normalized();
|
||||
v = v1*Math::cos(angle) + v3*Math::sin(angle);
|
||||
}
|
||||
|
||||
//construct matrix
|
||||
Matrix32 res(Math::atan2(v.y, v.x), Vector2::linear_interpolate(p1, p2, p_c));
|
||||
res.scale_basis(Vector2::linear_interpolate(s1, s2, p_c));
|
||||
return res;
|
||||
}
|
||||
|
||||
Matrix32::operator String() const {
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include "core_string_names.h"
|
||||
#include "translation.h"
|
||||
#include "os/os.h"
|
||||
#include "resource.h"
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
||||
@ -1301,6 +1302,10 @@ Array Object::_get_signal_connection_list(const String& p_signal) const{
|
||||
|
||||
void Object::get_signal_list(List<MethodInfo> *p_signals ) const {
|
||||
|
||||
if (!script.is_null()) {
|
||||
Ref<Script>(script)->get_script_signal_list(p_signals);
|
||||
}
|
||||
|
||||
ObjectTypeDB::get_signal_list(get_type_name(),p_signals);
|
||||
//find maybe usersignals?
|
||||
const StringName *S=NULL;
|
||||
@ -1312,6 +1317,7 @@ void Object::get_signal_list(List<MethodInfo> *p_signals ) const {
|
||||
p_signals->push_back(signal_map[*S].user);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1350,6 +1356,10 @@ Error Object::connect(const StringName& p_signal, Object *p_to_object, const Str
|
||||
Signal *s = signal_map.getptr(p_signal);
|
||||
if (!s) {
|
||||
bool signal_is_valid = ObjectTypeDB::has_signal(get_type_name(),p_signal);
|
||||
//check in script
|
||||
if (!signal_is_valid && !script.is_null() && Ref<Script>(script)->has_script_signal(p_signal))
|
||||
signal_is_valid=true;
|
||||
|
||||
if (!signal_is_valid) {
|
||||
ERR_EXPLAIN("Attempt to connect nonexistent signal '"+p_signal+"' to method '"+p_to_method+"'");
|
||||
ERR_FAIL_COND_V(!signal_is_valid,ERR_INVALID_PARAMETER);
|
||||
@ -1464,6 +1474,63 @@ StringName Object::tr(const StringName& p_message) const {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Object::_clear_internal_resource_paths(const Variant &p_var) {
|
||||
|
||||
switch(p_var.get_type()) {
|
||||
|
||||
case Variant::OBJECT: {
|
||||
|
||||
RES r = p_var;
|
||||
if (!r.is_valid())
|
||||
return;
|
||||
|
||||
if (!r->get_path().begins_with("res://") || r->get_path().find("::")==-1)
|
||||
return; //not an internal resource
|
||||
|
||||
Object *object=p_var;
|
||||
if (!object)
|
||||
return;
|
||||
|
||||
r->set_path("");
|
||||
r->clear_internal_resource_paths();
|
||||
} break;
|
||||
case Variant::ARRAY: {
|
||||
|
||||
Array a=p_var;
|
||||
for(int i=0;i<a.size();i++) {
|
||||
_clear_internal_resource_paths(a[i]);
|
||||
}
|
||||
|
||||
} break;
|
||||
case Variant::DICTIONARY: {
|
||||
|
||||
Dictionary d=p_var;
|
||||
List<Variant> keys;
|
||||
d.get_key_list(&keys);
|
||||
|
||||
for (List<Variant>::Element *E=keys.front();E;E=E->next()) {
|
||||
|
||||
_clear_internal_resource_paths(E->get());
|
||||
_clear_internal_resource_paths(d[E->get()]);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Object::clear_internal_resource_paths() {
|
||||
|
||||
List<PropertyInfo> pinfo;
|
||||
|
||||
get_property_list(&pinfo);
|
||||
|
||||
for(List<PropertyInfo>::Element *E=pinfo.front();E;E=E->next()) {
|
||||
|
||||
_clear_internal_resource_paths(get(E->get().name));
|
||||
}
|
||||
}
|
||||
|
||||
void Object::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("get_type"),&Object::get_type);
|
||||
|
@ -451,6 +451,8 @@ protected:
|
||||
Array _get_property_list_bind() const;
|
||||
Array _get_method_list_bind() const;
|
||||
|
||||
void _clear_internal_resource_paths(const Variant &p_var);
|
||||
|
||||
public: //should be protected, but bug in clang++
|
||||
static void initialize_type();
|
||||
_FORCE_INLINE_ static void register_custom_data_to_otdb() {};
|
||||
@ -599,6 +601,9 @@ public:
|
||||
|
||||
_FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate=p_enable; }
|
||||
_FORCE_INLINE_ bool can_translate_messages() const { return _can_translate; }
|
||||
|
||||
void clear_internal_resource_paths();
|
||||
|
||||
Object();
|
||||
virtual ~Object();
|
||||
|
||||
@ -651,6 +656,8 @@ public:
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
//needed by macros
|
||||
|
@ -173,6 +173,16 @@ bool InputEvent::is_action(const String& p_action) const {
|
||||
return InputMap::get_singleton()->event_is_action(*this,p_action);
|
||||
}
|
||||
|
||||
bool InputEvent::is_action_pressed(const String& p_action) const {
|
||||
|
||||
return is_action(p_action) && is_pressed() && !is_echo();
|
||||
}
|
||||
|
||||
bool InputEvent::is_action_released(const String& p_action) const {
|
||||
|
||||
return is_action(p_action) && !is_pressed();
|
||||
}
|
||||
|
||||
uint32_t InputEventKey::get_scancode_with_modifiers() const {
|
||||
|
||||
uint32_t sc=scancode;
|
||||
|
@ -287,6 +287,8 @@ struct InputEvent {
|
||||
|
||||
bool is_pressed() const;
|
||||
bool is_action(const String& p_action) const;
|
||||
bool is_action_pressed(const String& p_action) const;
|
||||
bool is_action_released(const String& p_action) const;
|
||||
bool is_echo() const;
|
||||
void set_as_action(const String& p_action, bool p_pressed);
|
||||
|
||||
|
@ -195,6 +195,17 @@ String Resource::get_path() const {
|
||||
return path_cache;
|
||||
}
|
||||
|
||||
void Resource::set_subindex(int p_sub_index) {
|
||||
|
||||
subindex=p_sub_index;
|
||||
}
|
||||
|
||||
int Resource::get_subindex() const{
|
||||
|
||||
return subindex;
|
||||
}
|
||||
|
||||
|
||||
void Resource::set_name(const String& p_name) {
|
||||
|
||||
name=p_name;
|
||||
@ -326,6 +337,7 @@ Resource::Resource() {
|
||||
last_modified_time=0;
|
||||
#endif
|
||||
|
||||
subindex=0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +99,7 @@ friend class ResourceCache;
|
||||
|
||||
String name;
|
||||
String path_cache;
|
||||
int subindex;
|
||||
|
||||
virtual bool _use_builtin_script() const { return true; }
|
||||
|
||||
@ -132,6 +133,9 @@ public:
|
||||
void set_path(const String& p_path,bool p_take_over=false);
|
||||
String get_path() const;
|
||||
|
||||
void set_subindex(int p_sub_index);
|
||||
int get_subindex() const;
|
||||
|
||||
Ref<Resource> duplicate(bool p_subresources=false);
|
||||
|
||||
void set_import_metadata(const Ref<ResourceImportMetadata>& p_metadata);
|
||||
|
@ -136,6 +136,14 @@ ScriptInstance::~ScriptInstance() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
ScriptCodeCompletionCache *ScriptCodeCompletionCache::singleton=NULL;
|
||||
ScriptCodeCompletionCache::ScriptCodeCompletionCache() {
|
||||
singleton=this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ScriptLanguage::frame() {
|
||||
|
||||
|
||||
|
@ -94,6 +94,10 @@ public:
|
||||
|
||||
virtual ScriptLanguage *get_language() const=0;
|
||||
|
||||
virtual bool has_script_signal(const StringName& p_signal) const=0;
|
||||
virtual void get_script_signal_list(List<MethodInfo> *r_signals) const=0;
|
||||
|
||||
|
||||
virtual void update_exports() {} //editor tool
|
||||
|
||||
|
||||
@ -122,6 +126,19 @@ public:
|
||||
virtual ~ScriptInstance();
|
||||
};
|
||||
|
||||
class ScriptCodeCompletionCache {
|
||||
|
||||
static ScriptCodeCompletionCache *singleton;
|
||||
public:
|
||||
|
||||
virtual RES get_cached_resource(const String& p_path)=0;
|
||||
|
||||
static ScriptCodeCompletionCache* get_sigleton() { return singleton; }
|
||||
|
||||
ScriptCodeCompletionCache();
|
||||
|
||||
};
|
||||
|
||||
class ScriptLanguage {
|
||||
public:
|
||||
|
||||
|
@ -282,6 +282,7 @@ void UndoRedo::undo() {
|
||||
return; //nothing to redo
|
||||
_process_operation_list(actions[current_action].undo_ops.front());
|
||||
current_action--;
|
||||
version--;
|
||||
}
|
||||
|
||||
void UndoRedo::clear_history() {
|
||||
@ -292,7 +293,7 @@ void UndoRedo::clear_history() {
|
||||
while(actions.size())
|
||||
_pop_history_tail();
|
||||
|
||||
version++;
|
||||
//version++;
|
||||
}
|
||||
|
||||
String UndoRedo::get_current_action_name() const {
|
||||
@ -326,7 +327,7 @@ void UndoRedo::set_commit_notify_callback(CommitNotifyCallback p_callback,void*
|
||||
|
||||
UndoRedo::UndoRedo() {
|
||||
|
||||
version=0;
|
||||
version=1;
|
||||
action_level=0;
|
||||
current_action=-1;
|
||||
max_steps=-1;
|
||||
@ -339,3 +340,126 @@ UndoRedo::~UndoRedo() {
|
||||
|
||||
clear_history();
|
||||
}
|
||||
|
||||
Variant UndoRedo::_add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
|
||||
|
||||
if (p_argcount<2) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument=0;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
if (p_args[0]->get_type()!=Variant::OBJECT) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||
r_error.argument=0;
|
||||
r_error.expected=Variant::OBJECT;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
if (p_args[1]->get_type()!=Variant::STRING) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||
r_error.argument=1;
|
||||
r_error.expected=Variant::STRING;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
r_error.error=Variant::CallError::CALL_OK;
|
||||
|
||||
Object* object = *p_args[0];
|
||||
String method = *p_args[1];
|
||||
|
||||
Variant v[VARIANT_ARG_MAX];
|
||||
|
||||
|
||||
for(int i=0;i<MIN(VARIANT_ARG_MAX,p_argcount-2);++i) {
|
||||
|
||||
v[i]=*p_args[i+2];
|
||||
}
|
||||
|
||||
add_do_method(object,method,v[0],v[1],v[2],v[3],v[4]);
|
||||
return Variant();
|
||||
}
|
||||
|
||||
Variant UndoRedo::_add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error) {
|
||||
|
||||
if (p_argcount<2) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
|
||||
r_error.argument=0;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
if (p_args[0]->get_type()!=Variant::OBJECT) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||
r_error.argument=0;
|
||||
r_error.expected=Variant::OBJECT;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
if (p_args[1]->get_type()!=Variant::STRING) {
|
||||
r_error.error=Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
|
||||
r_error.argument=1;
|
||||
r_error.expected=Variant::STRING;
|
||||
return Variant();
|
||||
}
|
||||
|
||||
r_error.error=Variant::CallError::CALL_OK;
|
||||
|
||||
Object* object = *p_args[0];
|
||||
String method = *p_args[1];
|
||||
|
||||
Variant v[VARIANT_ARG_MAX];
|
||||
|
||||
|
||||
for(int i=0;i<MIN(VARIANT_ARG_MAX,p_argcount-2);++i) {
|
||||
|
||||
v[i]=*p_args[i+2];
|
||||
}
|
||||
|
||||
add_undo_method(object,method,v[0],v[1],v[2],v[3],v[4]);
|
||||
return Variant();
|
||||
}
|
||||
|
||||
void UndoRedo::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("create_action","name","mergeable"),&UndoRedo::create_action, DEFVAL(false) );
|
||||
ObjectTypeDB::bind_method(_MD("commit_action"),&UndoRedo::commit_action);
|
||||
|
||||
//ObjectTypeDB::bind_method(_MD("add_do_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_do_method);
|
||||
//ObjectTypeDB::bind_method(_MD("add_undo_method","p_object", "p_method", "VARIANT_ARG_LIST"),&UndoRedo::add_undo_method);
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.name="add_do_method";
|
||||
mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object"));
|
||||
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
|
||||
Vector<Variant> defargs;
|
||||
for(int i=0;i<VARIANT_ARG_MAX;++i) {
|
||||
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
|
||||
defargs.push_back(Variant());
|
||||
}
|
||||
|
||||
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_do_method",&UndoRedo::_add_do_method,mi,defargs);
|
||||
}
|
||||
|
||||
{
|
||||
MethodInfo mi;
|
||||
mi.name="add_undo_method";
|
||||
mi.arguments.push_back( PropertyInfo( Variant::OBJECT, "object"));
|
||||
mi.arguments.push_back( PropertyInfo( Variant::STRING, "method"));
|
||||
Vector<Variant> defargs;
|
||||
for(int i=0;i<VARIANT_ARG_MAX;++i) {
|
||||
mi.arguments.push_back( PropertyInfo( Variant::NIL, "arg"+itos(i)));
|
||||
defargs.push_back(Variant());
|
||||
}
|
||||
|
||||
ObjectTypeDB::bind_native_method(METHOD_FLAGS_DEFAULT,"add_undo_method",&UndoRedo::_add_undo_method,mi,defargs);
|
||||
}
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_do_property","object", "property", "value:var"),&UndoRedo::add_do_property);
|
||||
ObjectTypeDB::bind_method(_MD("add_undo_property","object", "property", "value:var"),&UndoRedo::add_undo_property);
|
||||
ObjectTypeDB::bind_method(_MD("add_do_reference","object"),&UndoRedo::add_do_reference);
|
||||
ObjectTypeDB::bind_method(_MD("add_undo_reference","object"),&UndoRedo::add_undo_reference);
|
||||
ObjectTypeDB::bind_method(_MD("clear_history"),&UndoRedo::clear_history);
|
||||
ObjectTypeDB::bind_method(_MD("get_current_action_name"),&UndoRedo::get_current_action_name);
|
||||
ObjectTypeDB::bind_method(_MD("get_version"),&UndoRedo::get_version);
|
||||
}
|
||||
|
@ -38,9 +38,12 @@
|
||||
class UndoRedo : public Object {
|
||||
|
||||
OBJ_TYPE(UndoRedo,Object);
|
||||
OBJ_SAVE_TYPE( UndoRedo );
|
||||
public:
|
||||
|
||||
typedef void (*CommitNotifyCallback)(void *p_ud,const String& p_name);
|
||||
Variant _add_do_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
Variant _add_undo_method(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
|
||||
private:
|
||||
struct Operation {
|
||||
@ -81,6 +84,10 @@ private:
|
||||
CommitNotifyCallback callback;
|
||||
void* callback_ud;
|
||||
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
|
||||
void create_action(const String& p_name="",bool p_mergeable=false);
|
||||
|
@ -715,6 +715,8 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
|
||||
|
||||
VCALL_PTR0R( InputEvent, is_pressed );
|
||||
VCALL_PTR1R( InputEvent, is_action );
|
||||
VCALL_PTR1R( InputEvent, is_action_pressed );
|
||||
VCALL_PTR1R( InputEvent, is_action_released );
|
||||
VCALL_PTR0R( InputEvent, is_echo );
|
||||
VCALL_PTR2( InputEvent, set_as_action );
|
||||
|
||||
@ -750,6 +752,12 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var
|
||||
r_ret=Rect2(*p_args[0],*p_args[1],*p_args[2],*p_args[3]);
|
||||
}
|
||||
|
||||
static void Matrix32_init2(Variant& r_ret,const Variant** p_args) {
|
||||
|
||||
Matrix32 m(*p_args[0], *p_args[1]);
|
||||
r_ret=m;
|
||||
}
|
||||
|
||||
static void Matrix32_init3(Variant& r_ret,const Variant** p_args) {
|
||||
|
||||
Matrix32 m;
|
||||
@ -1534,6 +1542,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
|
||||
|
||||
ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_pressed,varray());
|
||||
ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action,STRING,"action",varray());
|
||||
ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action_pressed,STRING,"is_action_pressed",varray());
|
||||
ADDFUNC1(INPUT_EVENT,BOOL,InputEvent,is_action_released,STRING,"is_action_released",varray());
|
||||
ADDFUNC0(INPUT_EVENT,BOOL,InputEvent,is_echo,varray());
|
||||
ADDFUNC2(INPUT_EVENT,NIL,InputEvent,set_as_action,STRING,"action",BOOL,"pressed",varray());
|
||||
|
||||
@ -1544,6 +1554,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
|
||||
_VariantCall::add_constructor(_VariantCall::Rect2_init1,Variant::RECT2,"pos",Variant::VECTOR2,"size",Variant::VECTOR2);
|
||||
_VariantCall::add_constructor(_VariantCall::Rect2_init2,Variant::RECT2,"x",Variant::REAL,"y",Variant::REAL,"width",Variant::REAL,"height",Variant::REAL);
|
||||
|
||||
_VariantCall::add_constructor(_VariantCall::Matrix32_init2,Variant::MATRIX32,"rot",Variant::REAL,"pos",Variant::VECTOR2);
|
||||
_VariantCall::add_constructor(_VariantCall::Matrix32_init3,Variant::MATRIX32,"x_axis",Variant::VECTOR2,"y_axis",Variant::VECTOR2,"origin",Variant::VECTOR2);
|
||||
|
||||
_VariantCall::add_constructor(_VariantCall::Vector3_init1,Variant::VECTOR3,"x",Variant::REAL,"y",Variant::REAL,"z",Variant::REAL);
|
||||
|
@ -1,11 +0,0 @@
|
||||
::res://::1422910453
|
||||
floor.png::ImageTexture::1422910453::
|
||||
fog.gd::GDScript::1422910025::
|
||||
fog.png::ImageTexture::1422908128::
|
||||
fog.scn::PackedScene::1422909435::
|
||||
fog.xml::TileSet::1422909324::
|
||||
icon.png::ImageTexture::1422811193::
|
||||
tile_edit.scn::PackedScene::1422909313::
|
||||
troll.gd::GDScript::1422909940::
|
||||
troll.png::ImageTexture::1418669358::
|
||||
troll.scn::PackedScene::1418669358::
|
@ -3,12 +3,9 @@
|
||||
name="Motion Test"
|
||||
main_scene="res://motion.scn"
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
[display]
|
||||
|
||||
width=800
|
||||
height=600
|
||||
stretch_mode="2d"
|
||||
stretch_aspect="keep"
|
||||
>>>>>>> ab99671bb835a5fe24a092ec34afe1ad862ac254
|
||||
|
Binary file not shown.
@ -45,3 +45,4 @@ func _on_shot_body_enter( body ):
|
||||
#hit the tilemap
|
||||
_hit_something()
|
||||
pass # replace with function body
|
||||
|
||||
|
Binary file not shown.
@ -8783,7 +8783,7 @@
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_undo_redo" >
|
||||
<return type="Object">
|
||||
<return type="UndoRedo">
|
||||
</return>
|
||||
<description>
|
||||
</description>
|
||||
@ -23032,12 +23032,14 @@
|
||||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
Return whether the closest object the ray is pointing to is colliding with the vector, with the vector length considered.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider" qualifiers="const" >
|
||||
<return type="Object">
|
||||
</return>
|
||||
<description>
|
||||
Return the closest object the ray is pointing to. Note that this does not consider the length of the vector, so you must also use [is_colliding] to check if the object returned is actually colliding with the ray.
|
||||
</description>
|
||||
</method>
|
||||
<method name="get_collider_shape" qualifiers="const" >
|
||||
|
@ -1013,10 +1013,16 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
|
||||
|
||||
bool force_clamp_to_edge = !(texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height)!=texture->alloc_height || nearest_power_of_2(texture->alloc_width)!=texture->alloc_width);
|
||||
|
||||
if (!force_clamp_to_edge && texture->flags&VS::TEXTURE_FLAG_REPEAT && texture->target != GL_TEXTURE_CUBE_MAP) {
|
||||
if (!force_clamp_to_edge && (texture->flags&VS::TEXTURE_FLAG_REPEAT || texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
|
||||
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
if (texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT){
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );
|
||||
}
|
||||
else{
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
}
|
||||
} else {
|
||||
|
||||
//glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
|
||||
@ -1270,10 +1276,16 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) {
|
||||
|
||||
bool force_clamp_to_edge = !(p_flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) && (nearest_power_of_2(texture->alloc_height)!=texture->alloc_height || nearest_power_of_2(texture->alloc_width)!=texture->alloc_width);
|
||||
|
||||
if (!force_clamp_to_edge && texture->flags&VS::TEXTURE_FLAG_REPEAT && texture->target != GL_TEXTURE_CUBE_MAP) {
|
||||
if (!force_clamp_to_edge && (texture->flags&VS::TEXTURE_FLAG_REPEAT || texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT) && texture->target != GL_TEXTURE_CUBE_MAP) {
|
||||
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
if (texture->flags&VS::TEXTURE_FLAG_MIRRORED_REPEAT){
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );
|
||||
}
|
||||
else {
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
}
|
||||
} else {
|
||||
//glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
|
||||
glTexParameterf( texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
|
||||
@ -9536,6 +9548,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list,int p_z,const
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_TEXTURE,max_texture_units-3);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult);
|
||||
canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR,light->shadow_color);
|
||||
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,7 @@ uniform vec4 modulate;
|
||||
|
||||
uniform sampler2D light_texture;
|
||||
uniform vec4 light_color;
|
||||
uniform vec4 light_shadow_color;
|
||||
uniform float light_height;
|
||||
varying vec4 light_uv_interp;
|
||||
|
||||
@ -379,7 +380,8 @@ LIGHT_SHADER_CODE
|
||||
#if defined(USE_LIGHT_SHADOW_COLOR)
|
||||
color=mix(shadow_color,color,shadow_attenuation);
|
||||
#else
|
||||
color*=shadow_attenuation;
|
||||
//color*=shadow_attenuation;
|
||||
color=mix(light_shadow_color,color,shadow_attenuation);
|
||||
#endif
|
||||
//use shadows
|
||||
#endif
|
||||
|
@ -75,6 +75,9 @@ Error ResourceSaverPNG::save(const String &p_path,const RES& p_resource,uint32_t
|
||||
if (bool(texture->get_flags()&Texture::FLAG_CONVERT_TO_LINEAR)) {
|
||||
text+="tolinear=true\n";
|
||||
}
|
||||
if (bool(texture->get_flags()&Texture::FLAG_MIRRORED_REPEAT)) {
|
||||
text+="mirroredrepeat=true\n";
|
||||
}
|
||||
|
||||
if (text!="" || FileAccess::exists(p_path+".flags")) {
|
||||
|
||||
|
@ -28,15 +28,6 @@
|
||||
/*************************************************************************/
|
||||
#include "gd_compiler.h"
|
||||
#include "gd_script.h"
|
||||
/* TODO:
|
||||
|
||||
*AND and OR need early abort
|
||||
-Inheritance properly process (done?)
|
||||
*create built in initializer and constructor
|
||||
*assign operators
|
||||
*build arrays and dictionaries
|
||||
*call parent constructor
|
||||
*/
|
||||
|
||||
|
||||
void GDCompiler::_set_error(const String& p_error,const GDParser::Node *p_node) {
|
||||
@ -1397,13 +1388,14 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
|
||||
|
||||
|
||||
int index_from=0;
|
||||
Ref<GDNativeClass> native;
|
||||
|
||||
if (p_class->extends_used) {
|
||||
//do inheritance
|
||||
String path = p_class->extends_file;
|
||||
|
||||
Ref<GDScript> script;
|
||||
Ref<GDNativeClass> native;
|
||||
|
||||
|
||||
if (path!="") {
|
||||
//path (and optionally subclasses)
|
||||
@ -1573,7 +1565,35 @@ Error GDCompiler::_parse_class(GDScript *p_script,GDScript *p_owner,const GDPars
|
||||
//p_script->constants[constant->value].make_const();
|
||||
}
|
||||
|
||||
for(int i=0;i<p_class->_signals.size();i++) {
|
||||
|
||||
StringName name = p_class->_signals[i].name;
|
||||
|
||||
GDScript *c = p_script;
|
||||
|
||||
while(c) {
|
||||
|
||||
if (c->_signals.has(name)) {
|
||||
_set_error("Signal '"+name+"' redefined (in current or parent class)",p_class);
|
||||
return ERR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
if (c->base.is_valid()) {
|
||||
c=c->base.ptr();
|
||||
} else {
|
||||
c=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (native.is_valid()) {
|
||||
if (ObjectTypeDB::has_signal(native->get_name(),name)) {
|
||||
_set_error("Signal '"+name+"' redefined (original in native class '"+String(native->get_name())+"')",p_class);
|
||||
return ERR_ALREADY_EXISTS;
|
||||
}
|
||||
}
|
||||
|
||||
p_script->_signals[name]=p_class->_signals[i].arguments;
|
||||
}
|
||||
//parse sub-classes
|
||||
|
||||
for(int i=0;i<p_class->subclasses.size();i++) {
|
||||
|
@ -381,7 +381,12 @@ static Ref<Reference> _get_parent_class(GDCompletionContext& context) {
|
||||
|
||||
path=context.base_path.plus_file(path);
|
||||
}
|
||||
script = ResourceLoader::load(path);
|
||||
|
||||
if (ScriptCodeCompletionCache::get_sigleton())
|
||||
script = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
|
||||
else
|
||||
script = ResourceLoader::load(path);
|
||||
|
||||
if (script.is_null()) {
|
||||
return REF();
|
||||
}
|
||||
@ -1195,7 +1200,7 @@ static void _find_identifiers(GDCompletionContext& context,int p_line,bool p_onl
|
||||
}
|
||||
|
||||
static const char*_type_names[Variant::VARIANT_MAX]={
|
||||
"null","bool","int","float","String","Vector2","Rect2","Vector3","Matrix32","Plane","Quat","AABB","Matrix3","Trasnform",
|
||||
"null","bool","int","float","String","Vector2","Rect2","Vector3","Matrix32","Plane","Quat","AABB","Matrix3","Transform",
|
||||
"Color","Image","NodePath","RID","Object","InputEvent","Dictionary","Array","RawArray","IntArray","FloatArray","StringArray",
|
||||
"Vector2Array","Vector3Array","ColorArray"};
|
||||
|
||||
@ -1322,6 +1327,21 @@ static void _find_type_arguments(const GDParser::Node*p_node,int p_line,const St
|
||||
if (obj) {
|
||||
List<String> options;
|
||||
obj->get_argument_options(p_method,p_argidx,&options);
|
||||
if (obj->is_type("Node") && p_argidx==0 && (String(p_method)=="get_node" || String(p_method)=="has_node")) {
|
||||
|
||||
List<PropertyInfo> props;
|
||||
Globals::get_singleton()->get_property_list(&props);
|
||||
|
||||
for(List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
|
||||
|
||||
String s = E->get().name;
|
||||
if (!s.begins_with("autoload/"))
|
||||
continue;
|
||||
// print_line("found "+s);
|
||||
String name = s.get_slice("/",1);
|
||||
options.push_back("\"/root/"+name+"\"");
|
||||
}
|
||||
}
|
||||
for(List<String>::Element *E=options.front();E;E=E->next()) {
|
||||
|
||||
result.insert(E->get());
|
||||
@ -1661,7 +1681,9 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
|
||||
//print_line( p_code.replace(String::chr(0xFFFF),"<cursor>"));
|
||||
|
||||
GDParser p;
|
||||
Error err = p.parse(p_code,p_base_path,true);
|
||||
//Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false);
|
||||
|
||||
Error err = p.parse(p_code,p_base_path,false,"",true);
|
||||
bool isfunction=false;
|
||||
Set<String> options;
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "print_string.h"
|
||||
#include "io/resource_loader.h"
|
||||
#include "os/file_access.h"
|
||||
#include "script_language.h"
|
||||
|
||||
template<class T>
|
||||
T* GDParser::alloc_node() {
|
||||
@ -116,6 +117,14 @@ bool GDParser::_parse_arguments(Node* p_parent,Vector<Node*>& p_args,bool p_stat
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_CURSOR) {
|
||||
_make_completable_call(argidx);
|
||||
completion_node=p_parent;
|
||||
} else if (tokenizer->get_token()==GDTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type()==Variant::STRING && tokenizer->get_token(1)==GDTokenizer::TK_CURSOR) {
|
||||
//completing a string argument..
|
||||
completion_cursor=tokenizer->get_token_constant();
|
||||
|
||||
_make_completable_call(argidx);
|
||||
completion_node=p_parent;
|
||||
tokenizer->advance(1);
|
||||
return false;
|
||||
}
|
||||
|
||||
Node*arg = _parse_expression(p_parent,p_static);
|
||||
@ -277,7 +286,11 @@ GDParser::Node* GDParser::_parse_expression(Node *p_parent,bool p_static,bool p_
|
||||
if (!validating) {
|
||||
|
||||
//this can be too slow for just validating code
|
||||
res = ResourceLoader::load(path);
|
||||
if (for_completion && ScriptCodeCompletionCache::get_sigleton()) {
|
||||
res = ScriptCodeCompletionCache::get_sigleton()->get_cached_resource(path);
|
||||
} else {
|
||||
res = ResourceLoader::load(path);
|
||||
}
|
||||
if (!res.is_valid()) {
|
||||
_set_error("Can't preload resource at path: "+path);
|
||||
return NULL;
|
||||
@ -1520,8 +1533,10 @@ void GDParser::_parse_block(BlockNode *p_block,bool p_static) {
|
||||
op->arguments.push_back(assigned);
|
||||
p_block->statements.push_back(op);
|
||||
|
||||
_end_statement();
|
||||
|
||||
if (!_end_statement()) {
|
||||
_set_error("Expected end of statement (var)");
|
||||
return;
|
||||
}
|
||||
|
||||
} break;
|
||||
case GDTokenizer::TK_CF_IF: {
|
||||
@ -1946,8 +1961,10 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
_parse_extends(p_class);
|
||||
if (error_set)
|
||||
return;
|
||||
_end_statement();
|
||||
|
||||
if (!_end_statement()) {
|
||||
_set_error("Expected end of statement after extends");
|
||||
return;
|
||||
}
|
||||
|
||||
} break;
|
||||
case GDTokenizer::TK_PR_TOOL: {
|
||||
@ -2227,6 +2244,53 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
|
||||
//arguments
|
||||
} break;
|
||||
case GDTokenizer::TK_PR_SIGNAL: {
|
||||
tokenizer->advance();
|
||||
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
|
||||
_set_error("Expected identifier after 'signal'.");
|
||||
return;
|
||||
}
|
||||
|
||||
ClassNode::Signal sig;
|
||||
sig.name = tokenizer->get_token_identifier();
|
||||
tokenizer->advance();
|
||||
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_OPEN) {
|
||||
tokenizer->advance();
|
||||
while(true) {
|
||||
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
tokenizer->advance();
|
||||
break;
|
||||
}
|
||||
|
||||
if (tokenizer->get_token()!=GDTokenizer::TK_IDENTIFIER) {
|
||||
_set_error("Expected identifier in signal argument.");
|
||||
return;
|
||||
}
|
||||
|
||||
sig.arguments.push_back(tokenizer->get_token_identifier());
|
||||
tokenizer->advance();
|
||||
|
||||
if (tokenizer->get_token()==GDTokenizer::TK_COMMA) {
|
||||
tokenizer->advance();
|
||||
} else if (tokenizer->get_token()!=GDTokenizer::TK_PARENTHESIS_CLOSE) {
|
||||
_set_error("Expected ',' or ')' after signal parameter identifier.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p_class->_signals.push_back(sig);
|
||||
|
||||
if (!_end_statement()) {
|
||||
_set_error("Expected end of statement (signal)");
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
case GDTokenizer::TK_PR_EXPORT: {
|
||||
|
||||
tokenizer->advance();
|
||||
@ -2644,8 +2708,10 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
|
||||
p_class->variables.push_back(member);
|
||||
|
||||
_end_statement();
|
||||
|
||||
if (!_end_statement()) {
|
||||
_set_error("Expected end of statement (continue)");
|
||||
return;
|
||||
}
|
||||
} break;
|
||||
case GDTokenizer::TK_PR_CONST: {
|
||||
//variale declaration and (eventual) initialization
|
||||
@ -2682,8 +2748,10 @@ void GDParser::_parse_class(ClassNode *p_class) {
|
||||
|
||||
p_class->constant_expressions.push_back(constant);
|
||||
|
||||
_end_statement();
|
||||
|
||||
if (!_end_statement()) {
|
||||
_set_error("Expected end of statement (constant)");
|
||||
return;
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
@ -2759,6 +2827,8 @@ Error GDParser::_parse(const String& p_base_path) {
|
||||
|
||||
Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path, const String &p_self_path) {
|
||||
|
||||
for_completion=false;
|
||||
validating=false;
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
completion_class=NULL;
|
||||
@ -2779,7 +2849,7 @@ Error GDParser::parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p
|
||||
}
|
||||
|
||||
|
||||
Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path) {
|
||||
Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_just_validate, const String &p_self_path,bool p_for_completion) {
|
||||
|
||||
completion_type=COMPLETION_NONE;
|
||||
completion_node=NULL;
|
||||
@ -2796,6 +2866,7 @@ Error GDParser::parse(const String& p_code, const String& p_base_path, bool p_ju
|
||||
tt->set_code(p_code);
|
||||
|
||||
validating=p_just_validate;
|
||||
for_completion=p_for_completion;
|
||||
tokenizer=tt;
|
||||
Error ret = _parse(p_base_path);
|
||||
memdelete(tt);
|
||||
@ -2831,6 +2902,7 @@ void GDParser::clear() {
|
||||
current_function=NULL;
|
||||
|
||||
validating=false;
|
||||
for_completion=false;
|
||||
error_set=false;
|
||||
tab_level.clear();
|
||||
tab_level.push_back(0);
|
||||
|
@ -76,6 +76,7 @@ public:
|
||||
StringName extends_file;
|
||||
Vector<StringName> extends_class;
|
||||
|
||||
|
||||
struct Member {
|
||||
PropertyInfo _export;
|
||||
#ifdef TOOLS_ENABLED
|
||||
@ -92,11 +93,17 @@ public:
|
||||
Node *expression;
|
||||
};
|
||||
|
||||
struct Signal {
|
||||
StringName name;
|
||||
Vector<StringName> arguments;
|
||||
};
|
||||
|
||||
Vector<ClassNode*> subclasses;
|
||||
Vector<Member> variables;
|
||||
Vector<Constant> constant_expressions;
|
||||
Vector<FunctionNode*> functions;
|
||||
Vector<FunctionNode*> static_functions;
|
||||
Vector<Signal> _signals;
|
||||
BlockNode *initializer;
|
||||
ClassNode *owner;
|
||||
//Vector<Node*> initializers;
|
||||
@ -380,6 +387,7 @@ private:
|
||||
T* alloc_node();
|
||||
|
||||
bool validating;
|
||||
bool for_completion;
|
||||
int parenthesis;
|
||||
bool error_set;
|
||||
String error;
|
||||
@ -436,7 +444,7 @@ public:
|
||||
String get_error() const;
|
||||
int get_error_line() const;
|
||||
int get_error_column() const;
|
||||
Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="");
|
||||
Error parse(const String& p_code, const String& p_base_path="", bool p_just_validate=false,const String& p_self_path="",bool p_for_completion=false);
|
||||
Error parse_bytecode(const Vector<uint8_t> &p_bytecode,const String& p_base_path="",const String& p_self_path="");
|
||||
|
||||
const Node *get_parse_tree() const;
|
||||
|
@ -1756,6 +1756,12 @@ bool GDScript::_update_exports() {
|
||||
//print_line("found "+c->variables[i]._export.name);
|
||||
member_default_values_cache[c->variables[i].identifier]=c->variables[i].default_value;
|
||||
}
|
||||
|
||||
_signals.clear();
|
||||
|
||||
for(int i=0;i<c->_signals.size();i++) {
|
||||
_signals[c->_signals[i].name]=c->_signals[i].arguments;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//print_line("unchaged is "+get_path());
|
||||
@ -2100,6 +2106,47 @@ Ref<GDScript> GDScript::get_base() const {
|
||||
return base;
|
||||
}
|
||||
|
||||
bool GDScript::has_script_signal(const StringName& p_signal) const {
|
||||
if (_signals.has(p_signal))
|
||||
return true;
|
||||
if (base.is_valid()) {
|
||||
return base->has_script_signal(p_signal);
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
else if (base_cache.is_valid()){
|
||||
return base_cache->has_script_signal(p_signal);
|
||||
}
|
||||
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
|
||||
|
||||
for(const Map<StringName,Vector<StringName> >::Element *E=_signals.front();E;E=E->next()) {
|
||||
|
||||
MethodInfo mi;
|
||||
mi.name=E->key();
|
||||
for(int i=0;i<E->get().size();i++) {
|
||||
PropertyInfo arg;
|
||||
arg.name=E->get()[i];
|
||||
mi.arguments.push_back(arg);
|
||||
}
|
||||
r_signals->push_back(mi);
|
||||
}
|
||||
|
||||
if (base.is_valid()) {
|
||||
base->get_script_signal_list(r_signals);
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
else if (base_cache.is_valid()){
|
||||
base_cache->get_script_signal_list(r_signals);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
GDScript::GDScript() {
|
||||
|
||||
|
||||
@ -2131,7 +2178,6 @@ bool GDInstance::set(const StringName& p_name, const Variant& p_value) {
|
||||
{
|
||||
const Map<StringName,GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name);
|
||||
if (E) {
|
||||
members[E->get().index]=p_value;
|
||||
if (E->get().setter) {
|
||||
const Variant *val=&p_value;
|
||||
Variant::CallError err;
|
||||
@ -2140,6 +2186,8 @@ bool GDInstance::set(const StringName& p_name, const Variant& p_value) {
|
||||
return true; //function exists, call was successful
|
||||
}
|
||||
}
|
||||
else
|
||||
members[E->get().index] = p_value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2593,6 +2641,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
|
||||
"static",
|
||||
"float",
|
||||
"int",
|
||||
"signal",
|
||||
0};
|
||||
|
||||
|
||||
|
@ -260,6 +260,7 @@ friend class GDScriptLanguage;
|
||||
Map<StringName,GDFunction> member_functions;
|
||||
Map<StringName,MemberInfo> member_indices; //members are just indices to the instanced script.
|
||||
Map<StringName,Ref<GDScript> > subclasses;
|
||||
Map<StringName,Vector<StringName> > _signals;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
@ -318,6 +319,9 @@ public:
|
||||
const Map<StringName,GDFunction>& get_member_functions() const { return member_functions; }
|
||||
const Ref<GDNativeClass>& get_native() const { return native; }
|
||||
|
||||
virtual bool has_script_signal(const StringName& p_signal) const;
|
||||
virtual void get_script_signal_list(List<MethodInfo> *r_signals) const;
|
||||
|
||||
|
||||
bool is_tool() const { return tool; }
|
||||
Ref<GDScript> get_base() const;
|
||||
|
@ -568,7 +568,10 @@ void GDTokenizerText::_advance() {
|
||||
} else if( string_mode!=STRING_MULTILINE && CharType(GETCHAR(i))=='\n') {
|
||||
_make_error("Unexpected EOL at String.");
|
||||
return;
|
||||
|
||||
} else if( CharType(GETCHAR(i))==0xFFFF) {
|
||||
//string ends here, next will be TK
|
||||
i--;
|
||||
break;
|
||||
} else if (CharType(GETCHAR(i))=='\\') {
|
||||
//escaped characters...
|
||||
i++;
|
||||
@ -670,19 +673,19 @@ void GDTokenizerText::_advance() {
|
||||
while(true) {
|
||||
if (GETCHAR(i)=='.') {
|
||||
if (period_found || exponent_found) {
|
||||
_make_error("Invalid numeric constant at '.'");
|
||||
_make_error("Invalid numeric constant at '.'");
|
||||
return;
|
||||
}
|
||||
period_found=true;
|
||||
} else if (GETCHAR(i)=='x') {
|
||||
if (hexa_found || str.length()!=1 || !( (i==1 && str[0]=='0') || (i==2 && str[1]=='0' && str[0]=='-') ) ) {
|
||||
_make_error("Invalid numeric constant at 'x'");
|
||||
if (hexa_found || str.length()!=1 || !( (i==1 && str[0]=='0') || (i==2 && str[1]=='0' && str[0]=='-') ) ) {
|
||||
_make_error("Invalid numeric constant at 'x'");
|
||||
return;
|
||||
}
|
||||
hexa_found=true;
|
||||
} else if (!hexa_found && GETCHAR(i)=='e') {
|
||||
} else if (!hexa_found && GETCHAR(i)=='e') {
|
||||
if (hexa_found || exponent_found) {
|
||||
_make_error("Invalid numeric constant at 'e'");
|
||||
_make_error("Invalid numeric constant at 'e'");
|
||||
return;
|
||||
}
|
||||
exponent_found=true;
|
||||
@ -692,7 +695,7 @@ void GDTokenizerText::_advance() {
|
||||
|
||||
} else if ((GETCHAR(i)=='-' || GETCHAR(i)=='+') && exponent_found) {
|
||||
if (sign_found) {
|
||||
_make_error("Invalid numeric constant at '-'");
|
||||
_make_error("Invalid numeric constant at '-'");
|
||||
return;
|
||||
}
|
||||
sign_found=true;
|
||||
@ -703,20 +706,20 @@ void GDTokenizerText::_advance() {
|
||||
i++;
|
||||
}
|
||||
|
||||
if (!( _is_number(str[str.length()-1]) || (hexa_found && _is_hex(str[str.length()-1])))) {
|
||||
_make_error("Invalid numeric constant: "+str);
|
||||
if (!( _is_number(str[str.length()-1]) || (hexa_found && _is_hex(str[str.length()-1])))) {
|
||||
_make_error("Invalid numeric constant: "+str);
|
||||
return;
|
||||
}
|
||||
|
||||
INCPOS(str.length());
|
||||
if (hexa_found) {
|
||||
int val = str.hex_to_int();
|
||||
_make_constant(val);
|
||||
} else if (period_found) {
|
||||
if (hexa_found) {
|
||||
int val = str.hex_to_int();
|
||||
_make_constant(val);
|
||||
} else if (period_found) {
|
||||
real_t val = str.to_double();
|
||||
//print_line("*%*%*%*% to convert: "+str+" result: "+rtos(val));
|
||||
_make_constant(val);
|
||||
} else {
|
||||
} else {
|
||||
int val = str.to_int();
|
||||
_make_constant(val);
|
||||
|
||||
@ -825,7 +828,7 @@ void GDTokenizerText::_advance() {
|
||||
|
||||
_make_built_in_func(GDFunctions::Function(i));
|
||||
found=true;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -856,6 +859,7 @@ void GDTokenizerText::_advance() {
|
||||
{TK_PR_PRELOAD,"preload"},
|
||||
{TK_PR_ASSERT,"assert"},
|
||||
{TK_PR_YIELD,"yield"},
|
||||
{TK_PR_SIGNAL,"signal"},
|
||||
{TK_PR_CONST,"const"},
|
||||
//controlflow
|
||||
{TK_CF_IF,"if"},
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
TK_PR_PRELOAD,
|
||||
TK_PR_ASSERT,
|
||||
TK_PR_YIELD,
|
||||
TK_PR_SIGNAL,
|
||||
TK_BRACKET_OPEN,
|
||||
TK_BRACKET_CLOSE,
|
||||
TK_CURLY_BRACKET_OPEN,
|
||||
|
@ -61,7 +61,7 @@ void GridMapEditor::_menu_option(int p_option) {
|
||||
|
||||
case MENU_OPTION_CONFIGURE: {
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
case MENU_OPTION_LOCK_VIEW: {
|
||||
|
||||
@ -522,7 +522,9 @@ void GridMapEditor::_duplicate_paste() {
|
||||
}
|
||||
|
||||
bool GridMapEditor::forward_spatial_input_event(Camera* p_camera,const InputEvent& p_event) {
|
||||
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (edit_mode->get_selected()==0) { // regular click
|
||||
switch (p_event.type) {
|
||||
@ -706,9 +708,40 @@ struct _CGMEItemSort {
|
||||
|
||||
};
|
||||
|
||||
void GridMapEditor::_set_display_mode(int p_mode) {
|
||||
if (display_mode==p_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_mode == DISPLAY_LIST) {
|
||||
mode_list->set_pressed(true);
|
||||
mode_thumbnail->set_pressed(false);
|
||||
} else if (p_mode == DISPLAY_THUMBNAIL) {
|
||||
mode_list->set_pressed(false);
|
||||
mode_thumbnail->set_pressed(true);
|
||||
}
|
||||
|
||||
display_mode=p_mode;
|
||||
|
||||
update_pallete();
|
||||
}
|
||||
|
||||
void GridMapEditor::update_pallete() {
|
||||
int selected = theme_pallete->get_current();
|
||||
|
||||
theme_pallete->clear();
|
||||
if (display_mode == DISPLAY_THUMBNAIL) {
|
||||
theme_pallete->set_max_columns(0);
|
||||
theme_pallete->set_icon_mode(ItemList::ICON_MODE_TOP);
|
||||
} else if (display_mode == DISPLAY_LIST){
|
||||
theme_pallete->set_max_columns(1);
|
||||
theme_pallete->set_icon_mode(ItemList::ICON_MODE_LEFT);
|
||||
}
|
||||
|
||||
float min_size = EDITOR_DEF("grid_map/preview_size",64);
|
||||
theme_pallete->set_min_icon_size(Size2(min_size, min_size));
|
||||
theme_pallete->set_fixed_column_width(min_size*3/2);
|
||||
theme_pallete->set_max_text_lines(2);
|
||||
|
||||
Ref<MeshLibrary> theme = node->get_theme();
|
||||
|
||||
@ -720,10 +753,6 @@ void GridMapEditor::update_pallete() {
|
||||
Vector<int> ids;
|
||||
ids = theme->get_item_list();
|
||||
|
||||
TreeItem *root = theme_pallete->create_item(NULL);
|
||||
theme_pallete->set_hide_root(true);
|
||||
TreeItem *selected=NULL;
|
||||
|
||||
List<_CGMEItemSort> il;
|
||||
for(int i=0;i<ids.size();i++) {
|
||||
|
||||
@ -734,45 +763,31 @@ void GridMapEditor::update_pallete() {
|
||||
}
|
||||
il.sort();
|
||||
|
||||
int col=0;
|
||||
TreeItem *ti=NULL;
|
||||
int selected_col=0;
|
||||
int item = 0;
|
||||
|
||||
for(List<_CGMEItemSort>::Element *E=il.front();E;E=E->next()) {
|
||||
|
||||
int id = E->get().id;
|
||||
|
||||
if (col==0) {
|
||||
ti = theme_pallete->create_item(root);
|
||||
}
|
||||
theme_pallete->add_item("");
|
||||
|
||||
String name=theme->get_item_name(id);
|
||||
Ref<Texture> preview = theme->get_item_preview(id);
|
||||
|
||||
if (!preview.is_null()) {
|
||||
|
||||
ti->set_cell_mode(col,TreeItem::CELL_MODE_ICON);
|
||||
ti->set_icon(col,preview);
|
||||
ti->set_tooltip(col,name);
|
||||
} else {
|
||||
|
||||
ti->set_text(col,name);
|
||||
theme_pallete->set_item_icon(item, preview);
|
||||
theme_pallete->set_item_tooltip(item, name);
|
||||
}
|
||||
ti->set_metadata(col,id);
|
||||
|
||||
if (selected_pallete==id) {
|
||||
selected=ti;
|
||||
selected_col=col;
|
||||
if (name!="") {
|
||||
theme_pallete->set_item_text(item,name);
|
||||
}
|
||||
theme_pallete->set_item_metadata(item, id);
|
||||
|
||||
col++;
|
||||
if (col==theme_pallete->get_columns())
|
||||
col=0;
|
||||
|
||||
item++;
|
||||
}
|
||||
|
||||
if (selected)
|
||||
selected->select(selected_col);
|
||||
if (selected!=-1) {
|
||||
theme_pallete->select(selected);
|
||||
}
|
||||
|
||||
last_theme=theme.operator->();
|
||||
}
|
||||
@ -842,6 +857,9 @@ void GridMapEditor::edit(GridMap *p_gridmap) {
|
||||
VisualServer::get_singleton()->instance_geometry_set_flag(grid_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
|
||||
|
||||
}
|
||||
|
||||
VisualServer::get_singleton()->instance_geometry_set_flag(cursor_instance, VS::INSTANCE_FLAG_VISIBLE,false);
|
||||
|
||||
_clear_areas();
|
||||
|
||||
return;
|
||||
@ -951,7 +969,7 @@ void GridMapEditor::update_grid() {
|
||||
|
||||
grid_xform.origin.x-=1; //force update in hackish way.. what do i care
|
||||
|
||||
VS *vs = VS::get_singleton();
|
||||
//VS *vs = VS::get_singleton();
|
||||
|
||||
grid_ofs[edit_axis]=edit_floor[edit_axis]*node->get_cell_size();
|
||||
|
||||
@ -976,7 +994,7 @@ void GridMapEditor::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
theme_pallete->connect("cell_selected", this,"_item_selected_cbk");
|
||||
theme_pallete->connect("item_selected", this,"_item_selected_cbk");
|
||||
edit_mode->connect("item_selected", this,"_edit_mode_changed");
|
||||
area_list->connect("item_edited", this,"_area_renamed");
|
||||
area_list->connect("item_selected", this,"_area_selected");
|
||||
@ -1014,7 +1032,7 @@ void GridMapEditor::_notification(int p_what) {
|
||||
if (xf!=grid_xform) {
|
||||
for(int i=0;i<3;i++) {
|
||||
|
||||
|
||||
|
||||
VS::get_singleton()->instance_set_transform(grid_instance[i],xf * edit_grid_xform);
|
||||
}
|
||||
grid_xform=xf;
|
||||
@ -1043,7 +1061,9 @@ void GridMapEditor::_notification(int p_what) {
|
||||
}
|
||||
|
||||
void GridMapEditor::_update_cursor_instance() {
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cursor_instance.is_valid())
|
||||
VisualServer::get_singleton()->free(cursor_instance);
|
||||
@ -1063,18 +1083,8 @@ void GridMapEditor::_update_cursor_instance() {
|
||||
|
||||
}
|
||||
|
||||
void GridMapEditor::_item_selected_cbk() {
|
||||
|
||||
TreeItem *it = theme_pallete->get_selected();
|
||||
if (it) {
|
||||
|
||||
selected_pallete=it->get_metadata(theme_pallete->get_selected_column());
|
||||
|
||||
} else {
|
||||
|
||||
selected_pallete=-1;
|
||||
|
||||
}
|
||||
void GridMapEditor::_item_selected_cbk(int idx) {
|
||||
selected_pallete=theme_pallete->get_item_metadata(idx);
|
||||
|
||||
_update_cursor_instance();
|
||||
|
||||
@ -1092,7 +1102,9 @@ void GridMapEditor::_clear_areas() {
|
||||
}
|
||||
|
||||
void GridMapEditor::_update_areas_display() {
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
_clear_areas();
|
||||
List<int> areas;
|
||||
@ -1179,7 +1191,7 @@ void GridMapEditor::_bind_methods() {
|
||||
ObjectTypeDB::bind_method("_area_selected",&GridMapEditor::_area_selected);
|
||||
ObjectTypeDB::bind_method("_floor_changed",&GridMapEditor::_floor_changed);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"), &GridMapEditor::_set_display_mode);
|
||||
}
|
||||
|
||||
|
||||
@ -1240,6 +1252,9 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
|
||||
clip_mode=CLIP_DISABLED;
|
||||
options->get_popup()->connect("item_pressed", this,"_menu_option");
|
||||
|
||||
HBoxContainer *hb = memnew( HBoxContainer );
|
||||
add_child(hb);
|
||||
hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
edit_mode = memnew(OptionButton);
|
||||
edit_mode->set_area_as_parent_rect();
|
||||
@ -1247,13 +1262,27 @@ GridMapEditor::GridMapEditor(EditorNode *p_editor) {
|
||||
edit_mode->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_END,14);;
|
||||
edit_mode->add_item("Tiles");
|
||||
edit_mode->add_item("Areas");
|
||||
add_child(edit_mode);
|
||||
hb->add_child(edit_mode);
|
||||
edit_mode->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
mode_thumbnail = memnew( ToolButton );
|
||||
mode_thumbnail->set_toggle_mode(true);
|
||||
mode_thumbnail->set_pressed(true);
|
||||
mode_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons"));
|
||||
hb->add_child(mode_thumbnail);
|
||||
mode_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL));
|
||||
|
||||
mode_list = memnew( ToolButton );
|
||||
mode_list->set_toggle_mode(true);
|
||||
mode_list->set_pressed(false);
|
||||
mode_list->set_icon(p_editor->get_gui_base()->get_icon("FileList", "EditorIcons"));
|
||||
hb->add_child(mode_list);
|
||||
mode_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST));
|
||||
|
||||
display_mode = DISPLAY_THUMBNAIL;
|
||||
selected_area=-1;
|
||||
|
||||
|
||||
theme_pallete = memnew( Tree );
|
||||
theme_pallete->set_columns(3);
|
||||
theme_pallete = memnew( ItemList );
|
||||
add_child(theme_pallete);
|
||||
theme_pallete->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
|
@ -40,10 +40,8 @@
|
||||
class SpatialEditorPlugin;
|
||||
|
||||
class GridMapEditor : public VBoxContainer {
|
||||
|
||||
OBJ_TYPE(GridMapEditor, VBoxContainer );
|
||||
|
||||
|
||||
enum {
|
||||
|
||||
GRID_CURSOR_SIZE=50
|
||||
@ -66,6 +64,10 @@ class GridMapEditor : public VBoxContainer {
|
||||
CLIP_BELOW
|
||||
};
|
||||
|
||||
enum DisplayMode {
|
||||
DISPLAY_THUMBNAIL,
|
||||
DISPLAY_LIST
|
||||
};
|
||||
|
||||
UndoRedo *undo_redo;
|
||||
InputAction input_action;
|
||||
@ -73,6 +75,8 @@ class GridMapEditor : public VBoxContainer {
|
||||
MenuButton * options;
|
||||
SpinBox *floor;
|
||||
OptionButton *edit_mode;
|
||||
ToolButton *mode_thumbnail;
|
||||
ToolButton *mode_list;
|
||||
HBoxContainer *spatial_editor_hb;
|
||||
|
||||
struct SetItem {
|
||||
@ -132,6 +136,7 @@ class GridMapEditor : public VBoxContainer {
|
||||
Vector3 cursor_origin;
|
||||
Vector3 last_mouseover;
|
||||
|
||||
int display_mode;
|
||||
int selected_pallete;
|
||||
int selected_area;
|
||||
int cursor_rot;
|
||||
@ -183,9 +188,10 @@ class GridMapEditor : public VBoxContainer {
|
||||
void _configure();
|
||||
void _menu_option(int);
|
||||
void update_pallete();
|
||||
Tree *theme_pallete;
|
||||
void _set_display_mode(int p_mode);
|
||||
ItemList *theme_pallete;
|
||||
Tree *area_list;
|
||||
void _item_selected_cbk();
|
||||
void _item_selected_cbk(int idx);
|
||||
void _update_cursor_transform();
|
||||
void _update_cursor_instance();
|
||||
void _update_clip();
|
||||
|
@ -1113,7 +1113,9 @@ void OS_OSX::warp_mouse_pos(const Point2& p_to) {
|
||||
NSPoint localPoint = { p_to.x, p_to.y };
|
||||
|
||||
NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil];
|
||||
NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(NSRect){.origin=pointInWindow}].origin;
|
||||
NSRect pointInWindowRect;
|
||||
pointInWindowRect.origin = pointInWindow;
|
||||
NSPoint pointOnScreen = [[window_view window] convertRectToScreen:pointInWindowRect].origin;
|
||||
|
||||
//point in scren coords
|
||||
CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y};
|
||||
|
@ -4,7 +4,7 @@ void BackBufferCopy::_update_copy_mode() {
|
||||
|
||||
switch(copy_mode) {
|
||||
|
||||
case COPY_MODE_DISALED: {
|
||||
case COPY_MODE_DISABLED: {
|
||||
|
||||
VS::get_singleton()->canvas_item_set_copy_to_backbuffer(get_canvas_item(),false,Rect2());
|
||||
} break;
|
||||
@ -58,7 +58,7 @@ void BackBufferCopy::_bind_methods() {
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"copy_mode",PROPERTY_HINT_ENUM,"Disabled,Rect,Viewport"),_SCS("set_copy_mode"),_SCS("get_copy_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::RECT2,"rect"),_SCS("set_rect"),_SCS("get_rect"));
|
||||
|
||||
BIND_CONSTANT( COPY_MODE_DISALED );
|
||||
BIND_CONSTANT( COPY_MODE_DISABLED );
|
||||
BIND_CONSTANT( COPY_MODE_RECT );
|
||||
BIND_CONSTANT( COPY_MODE_VIEWPORT );
|
||||
|
||||
|
@ -7,7 +7,7 @@ class BackBufferCopy : public Node2D {
|
||||
OBJ_TYPE( BackBufferCopy,Node2D);
|
||||
public:
|
||||
enum CopyMode {
|
||||
COPY_MODE_DISALED,
|
||||
COPY_MODE_DISABLED,
|
||||
COPY_MODE_RECT,
|
||||
COPY_MODE_VIEWPORT
|
||||
};
|
||||
|
@ -237,6 +237,16 @@ float Light2D::get_shadow_esm_multiplier() const{
|
||||
return shadow_esm_multiplier;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_color( const Color& p_shadow_color) {
|
||||
shadow_color=p_shadow_color;
|
||||
VS::get_singleton()->canvas_light_set_shadow_color(canvas_light,shadow_color);
|
||||
}
|
||||
|
||||
Color Light2D::get_shadow_color() const {
|
||||
return shadow_color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Light2D::_notification(int p_what) {
|
||||
|
||||
@ -313,6 +323,10 @@ void Light2D::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_esm_multiplier","multiplier"),&Light2D::set_shadow_esm_multiplier);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_esm_multiplier"),&Light2D::get_shadow_esm_multiplier);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_color","shadow_color"),&Light2D::set_shadow_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_color"),&Light2D::get_shadow_color);
|
||||
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset"));
|
||||
@ -327,6 +341,7 @@ void Light2D::_bind_methods() {
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::COLOR,"shadow/color"),_SCS("set_shadow_color"),_SCS("get_shadow_color"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_shadow_mask"),_SCS("get_item_shadow_mask"));
|
||||
@ -356,6 +371,7 @@ Light2D::Light2D() {
|
||||
shadow_buffer_size=2048;
|
||||
shadow_esm_multiplier=80;
|
||||
energy=1.0;
|
||||
shadow_color=Color(0,0,0,0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,7 @@ private:
|
||||
bool enabled;
|
||||
bool shadow;
|
||||
Color color;
|
||||
Color shadow_color;
|
||||
float height;
|
||||
float _scale;
|
||||
float energy;
|
||||
@ -95,6 +96,10 @@ public:
|
||||
void set_shadow_esm_multiplier( float p_multiplier);
|
||||
float get_shadow_esm_multiplier() const;
|
||||
|
||||
void set_shadow_color( const Color& p_shadow_color);
|
||||
Color get_shadow_color() const;
|
||||
|
||||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
Light2D();
|
||||
|
@ -155,6 +155,11 @@ void VisibilityEnabler2D::_screen_enter() {
|
||||
_change_node_state(E->key(),true);
|
||||
}
|
||||
|
||||
if (enabler[ENABLER_PARENT_FIXED_PROCESS] && get_parent())
|
||||
get_parent()->set_fixed_process(true);
|
||||
if (enabler[ENABLER_PARENT_PROCESS] && get_parent())
|
||||
get_parent()->set_process(true);
|
||||
|
||||
visible=true;
|
||||
}
|
||||
|
||||
@ -165,6 +170,11 @@ void VisibilityEnabler2D::_screen_exit(){
|
||||
_change_node_state(E->key(),false);
|
||||
}
|
||||
|
||||
if (enabler[ENABLER_PARENT_FIXED_PROCESS] && get_parent())
|
||||
get_parent()->set_fixed_process(false);
|
||||
if (enabler[ENABLER_PARENT_PROCESS] && get_parent())
|
||||
get_parent()->set_process(false);
|
||||
|
||||
visible=false;
|
||||
}
|
||||
|
||||
@ -235,6 +245,12 @@ void VisibilityEnabler2D::_notification(int p_what){
|
||||
|
||||
_find_nodes(from);
|
||||
|
||||
if (enabler[ENABLER_PARENT_FIXED_PROCESS] && get_parent())
|
||||
get_parent()->set_fixed_process(false);
|
||||
if (enabler[ENABLER_PARENT_PROCESS] && get_parent())
|
||||
get_parent()->set_process(false);
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
@ -317,10 +333,14 @@ void VisibilityEnabler2D::_bind_methods(){
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_animations"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_ANIMATIONS );
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/freeze_bodies"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_FREEZE_BODIES);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/pause_particles"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PAUSE_PARTICLES);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/process_parent"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PARENT_PROCESS);
|
||||
ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"enabler/fixed_process_parent"),_SCS("set_enabler"),_SCS("is_enabler_enabled"), ENABLER_PARENT_FIXED_PROCESS);
|
||||
|
||||
BIND_CONSTANT( ENABLER_FREEZE_BODIES );
|
||||
BIND_CONSTANT( ENABLER_PAUSE_ANIMATIONS );
|
||||
BIND_CONSTANT( ENABLER_PAUSE_PARTICLES );
|
||||
BIND_CONSTANT( ENABLER_PARENT_PROCESS );
|
||||
BIND_CONSTANT( ENABLER_PARENT_FIXED_PROCESS );
|
||||
BIND_CONSTANT( ENABLER_MAX);
|
||||
}
|
||||
|
||||
@ -341,6 +361,8 @@ VisibilityEnabler2D::VisibilityEnabler2D() {
|
||||
|
||||
for(int i=0;i<ENABLER_MAX;i++)
|
||||
enabler[i]=true;
|
||||
enabler[ENABLER_PARENT_PROCESS]=false;
|
||||
enabler[ENABLER_PARENT_FIXED_PROCESS]=false;
|
||||
|
||||
visible=false;
|
||||
|
||||
|
@ -74,6 +74,8 @@ public:
|
||||
ENABLER_PAUSE_ANIMATIONS,
|
||||
ENABLER_FREEZE_BODIES,
|
||||
ENABLER_PAUSE_PARTICLES,
|
||||
ENABLER_PARENT_PROCESS,
|
||||
ENABLER_PARENT_FIXED_PROCESS,
|
||||
ENABLER_MAX
|
||||
};
|
||||
|
||||
|
@ -48,6 +48,7 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
|
||||
|
||||
points.remove(grabbed);
|
||||
grabbed=-1;
|
||||
grabbing=false;
|
||||
update();
|
||||
emit_signal("ramp_changed");
|
||||
accept_event();
|
||||
@ -67,12 +68,38 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
|
||||
{
|
||||
points.remove(grabbed);
|
||||
grabbed=-1;
|
||||
grabbing=false;
|
||||
update();
|
||||
emit_signal("ramp_changed");
|
||||
accept_event();
|
||||
}
|
||||
}
|
||||
|
||||
//Hold alt key to duplicate selected color
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed && p_event.key.mod.alt ) {
|
||||
|
||||
int x = p_event.mouse_button.x;
|
||||
grabbed=_get_point_from_pos(x);
|
||||
|
||||
if( grabbed != -1 ) {
|
||||
int total_w = get_size().width-get_size().height-3;
|
||||
ColorRamp::Point newPoint = points[grabbed];
|
||||
newPoint.offset=CLAMP(x/float(total_w),0,1);
|
||||
|
||||
points.push_back(newPoint);
|
||||
points.sort();
|
||||
for(int i=0;i<points.size();++i) {
|
||||
if (points[i].offset==newPoint.offset) {
|
||||
grabbed=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
emit_signal("ramp_changed");
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
|
||||
|
||||
update();
|
||||
@ -158,6 +185,33 @@ void ColorRampEdit::_input_event(const InputEvent& p_event) {
|
||||
|
||||
int x = p_event.mouse_motion.x;
|
||||
float newofs = CLAMP(x/float(total_w),0,1);
|
||||
|
||||
//Snap to nearest point if holding shift
|
||||
if (p_event.key.mod.shift) {
|
||||
float snap_treshhold = 0.03;
|
||||
float smallest_ofs = snap_treshhold;
|
||||
bool founded = false;
|
||||
int nearest_point;
|
||||
for(int i=0;i<points.size();++i) {
|
||||
if (i != grabbed) {
|
||||
float temp_ofs = ABS(points[i].offset - newofs);
|
||||
if (temp_ofs < smallest_ofs) {
|
||||
smallest_ofs = temp_ofs;
|
||||
nearest_point = i;
|
||||
if (founded)
|
||||
break;
|
||||
founded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (founded) {
|
||||
if (points[nearest_point].offset < newofs)
|
||||
newofs = points[nearest_point].offset+0.00001;
|
||||
else
|
||||
newofs = points[nearest_point].offset-0.00001;
|
||||
newofs = CLAMP(newofs,0,1);
|
||||
}
|
||||
}
|
||||
|
||||
bool valid=true;
|
||||
for(int i=0;i<points.size();i++) {
|
||||
|
@ -686,7 +686,7 @@ void FileDialog::set_default_show_hidden_files(bool p_show) {
|
||||
|
||||
FileDialog::FileDialog() {
|
||||
|
||||
show_hidden_files=true;
|
||||
show_hidden_files=default_show_hidden_files;
|
||||
|
||||
VBoxContainer *vbc = memnew( VBoxContainer );
|
||||
add_child(vbc);
|
||||
|
@ -11,6 +11,7 @@ void ItemList::add_item(const String& p_item,const Ref<Texture>& p_texture,bool
|
||||
item.selectable=p_selectable;
|
||||
item.selected=false;
|
||||
item.disabled=false;
|
||||
item.custom_bg=Color(0,0,0,0);
|
||||
items.push_back(item);
|
||||
|
||||
update();
|
||||
@ -26,6 +27,7 @@ void ItemList::add_icon_item(const Ref<Texture>& p_item,bool p_selectable){
|
||||
item.selectable=p_selectable;
|
||||
item.selected=false;
|
||||
item.disabled=false;
|
||||
item.custom_bg=Color(0,0,0,0);
|
||||
items.push_back(item);
|
||||
|
||||
update();
|
||||
@ -85,6 +87,23 @@ Ref<Texture> ItemList::get_item_icon(int p_idx) const{
|
||||
|
||||
}
|
||||
|
||||
void ItemList::set_item_custom_bg_color(int p_idx,const Color& p_custom_bg_color) {
|
||||
|
||||
ERR_FAIL_INDEX(p_idx,items.size());
|
||||
|
||||
items[p_idx].custom_bg=p_custom_bg_color;
|
||||
|
||||
}
|
||||
|
||||
Color ItemList::get_item_custom_bg_color(int p_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_idx,items.size(),Color());
|
||||
|
||||
return items[p_idx].custom_bg;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ItemList::set_item_tag_icon(int p_idx,const Ref<Texture>& p_tag_icon){
|
||||
|
||||
@ -635,6 +654,7 @@ void ItemList::_notification(int p_what) {
|
||||
Ref<Font> font = get_font("font");
|
||||
Color guide_color = get_color("guide_color");
|
||||
Color font_color = get_color("font_color");
|
||||
Color font_color_selected = get_color("font_color_selected");
|
||||
int font_height = font->get_height();
|
||||
Vector<int> line_size_cache;
|
||||
Vector<int> line_limit_cache;
|
||||
@ -781,6 +801,11 @@ void ItemList::_notification(int p_what) {
|
||||
if (current_columns==1) {
|
||||
rcache.size.width = width-rcache.pos.x;
|
||||
}
|
||||
if (items[i].custom_bg.a>0.001) {
|
||||
Rect2 r=rcache;
|
||||
r.pos+=base_ofs;
|
||||
draw_rect(r,items[i].custom_bg);
|
||||
}
|
||||
if (items[i].selected) {
|
||||
Rect2 r=rcache;
|
||||
r.pos+=base_ofs;
|
||||
@ -864,7 +889,7 @@ void ItemList::_notification(int p_what) {
|
||||
if (line>=max_text_lines)
|
||||
break;
|
||||
}
|
||||
ofs+=font->draw_char(get_canvas_item(),text_ofs+Vector2(ofs+(max_len-line_size_cache[line])/2,line*(font_height+line_separation)).floor(),items[i].text[j],items[i].text[j+1],font_color);
|
||||
ofs+=font->draw_char(get_canvas_item(),text_ofs+Vector2(ofs+(max_len-line_size_cache[line])/2,line*(font_height+line_separation)).floor(),items[i].text[j],items[i].text[j+1],items[i].selected?font_color_selected:font_color);
|
||||
}
|
||||
|
||||
//special multiline mode
|
||||
@ -884,7 +909,7 @@ void ItemList::_notification(int p_what) {
|
||||
text_ofs+=base_ofs;
|
||||
text_ofs+=items[i].rect_cache.pos;
|
||||
|
||||
draw_string(font,text_ofs,items[i].text,font_color,max_len+1);
|
||||
draw_string(font,text_ofs,items[i].text,items[i].selected?font_color_selected:font_color,max_len+1);
|
||||
}
|
||||
|
||||
|
||||
@ -954,6 +979,30 @@ String ItemList::get_tooltip(const Point2& p_pos) const {
|
||||
|
||||
}
|
||||
|
||||
void ItemList::sort_items_by_text() {
|
||||
items.sort();
|
||||
update();
|
||||
if (select_mode==SELECT_SINGLE) {
|
||||
for(int i=0;i<items.size();i++) {
|
||||
if (items[i].selected) {
|
||||
select(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ItemList::find_metadata(const Variant& p_metadata) const {
|
||||
|
||||
for(int i=0;i<items.size();i++) {
|
||||
if (items[i].metadata==p_metadata) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
}
|
||||
|
||||
void ItemList::_bind_methods(){
|
||||
|
||||
@ -972,6 +1021,12 @@ void ItemList::_bind_methods(){
|
||||
ObjectTypeDB::bind_method(_MD("set_item_disabled","idx","disabled"),&ItemList::set_item_disabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_item_disabled","idx"),&ItemList::is_item_disabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_item_metadata","idx","metadata"),&ItemList::set_item_metadata);
|
||||
ObjectTypeDB::bind_method(_MD("get_item_metadata","idx"),&ItemList::get_item_metadata);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_item_custom_bg_color","idx","custom_bg_color"),&ItemList::set_item_custom_bg_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_item_custom_bg_color","idx"),&ItemList::get_item_custom_bg_color);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_item_tooltip","idx","tooltip"),&ItemList::set_item_tooltip);
|
||||
ObjectTypeDB::bind_method(_MD("get_item_tooltip","idx"),&ItemList::get_item_tooltip);
|
||||
|
||||
@ -983,6 +1038,7 @@ void ItemList::_bind_methods(){
|
||||
ObjectTypeDB::bind_method(_MD("remove_item","idx"),&ItemList::remove_item);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("clear"),&ItemList::clear);
|
||||
ObjectTypeDB::bind_method(_MD("sort_items_by_text"),&ItemList::clear);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_fixed_column_width","width"),&ItemList::set_fixed_column_width);
|
||||
ObjectTypeDB::bind_method(_MD("get_fixed_column_width"),&ItemList::get_fixed_column_width);
|
||||
|
@ -29,8 +29,12 @@ private:
|
||||
bool disabled;
|
||||
Variant metadata;
|
||||
String tooltip;
|
||||
Color custom_bg;
|
||||
|
||||
|
||||
Rect2 rect_cache;
|
||||
|
||||
bool operator<(const Item& p_another) const { return text<p_another.text; }
|
||||
};
|
||||
|
||||
int current;
|
||||
@ -85,6 +89,9 @@ public:
|
||||
void set_item_tooltip(int p_idx,const String& p_tooltip);
|
||||
String get_item_tooltip(int p_idx) const;
|
||||
|
||||
void set_item_custom_bg_color(int p_idx,const Color& p_custom_bg_color);
|
||||
Color get_item_custom_bg_color(int p_idx) const;
|
||||
|
||||
void select(int p_idx,bool p_single=true);
|
||||
void unselect(int p_idx);
|
||||
bool is_selected(int p_idx) const;
|
||||
@ -118,6 +125,8 @@ public:
|
||||
|
||||
void ensure_current_is_visible();
|
||||
|
||||
void sort_items_by_text();
|
||||
int find_metadata(const Variant& p_metadata) const;
|
||||
|
||||
virtual String get_tooltip(const Point2& p_pos) const;
|
||||
|
||||
|
@ -77,8 +77,8 @@ void Tabs::_input_event(const InputEvent& p_event) {
|
||||
for(int i=0;i<tabs.size();i++) {
|
||||
|
||||
int ofs=tabs[i].ofs_cache;
|
||||
|
||||
if (pos.x < ofs) {
|
||||
int size = tabs[i].ofs_cache;
|
||||
if (pos.x >=tabs[i].ofs_cache && pos.x<tabs[i].ofs_cache+tabs[i].size_cache) {
|
||||
|
||||
found=i;
|
||||
break;
|
||||
@ -89,6 +89,7 @@ void Tabs::_input_event(const InputEvent& p_event) {
|
||||
if (found!=-1) {
|
||||
|
||||
set_current_tab(found);
|
||||
emit_signal("tab_changed",found);
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,8 +118,22 @@ void Tabs::_notification(int p_what) {
|
||||
|
||||
int w=0;
|
||||
|
||||
int mw = get_minimum_size().width;
|
||||
|
||||
if (tab_align==ALIGN_CENTER) {
|
||||
w=(get_size().width-mw)/2;
|
||||
} else if (tab_align==ALIGN_RIGHT) {
|
||||
w=get_size().width-mw;
|
||||
|
||||
}
|
||||
|
||||
if (w<0) {
|
||||
w=0;
|
||||
}
|
||||
|
||||
for(int i=0;i<tabs.size();i++) {
|
||||
|
||||
tabs[i].ofs_cache=w;
|
||||
|
||||
String s = tabs[i].text;
|
||||
int lsize=0;
|
||||
@ -171,7 +186,7 @@ void Tabs::_notification(int p_what) {
|
||||
|
||||
w+=slen+sb->get_margin(MARGIN_RIGHT);
|
||||
|
||||
tabs[i].ofs_cache=w;
|
||||
tabs[i].size_cache=w-tabs[i].ofs_cache;
|
||||
|
||||
}
|
||||
|
||||
@ -195,7 +210,7 @@ void Tabs::set_current_tab(int p_current) {
|
||||
current=p_current;
|
||||
|
||||
_change_notify("current_tab");
|
||||
emit_signal("tab_changed",current);
|
||||
//emit_signal("tab_changed",current);
|
||||
update();
|
||||
}
|
||||
|
||||
@ -249,6 +264,12 @@ void Tabs::add_tab(const String& p_str,const Ref<Texture>& p_icon) {
|
||||
|
||||
}
|
||||
|
||||
void Tabs::clear_tabs() {
|
||||
tabs.clear();
|
||||
current=0;
|
||||
update();
|
||||
}
|
||||
|
||||
void Tabs::remove_tab(int p_idx) {
|
||||
|
||||
ERR_FAIL_INDEX(p_idx,tabs.size());
|
||||
@ -263,10 +284,21 @@ void Tabs::remove_tab(int p_idx) {
|
||||
if (current>=tabs.size())
|
||||
current=tabs.size()-1;
|
||||
|
||||
emit_signal("tab_changed",current);
|
||||
//emit_signal("tab_changed",current);
|
||||
|
||||
}
|
||||
|
||||
void Tabs::set_tab_align(TabAlign p_align) {
|
||||
|
||||
tab_align=p_align;
|
||||
update();
|
||||
}
|
||||
|
||||
Tabs::TabAlign Tabs::get_tab_align() const {
|
||||
|
||||
return tab_align;
|
||||
}
|
||||
|
||||
|
||||
void Tabs::_bind_methods() {
|
||||
|
||||
@ -280,15 +312,21 @@ void Tabs::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("get_tab_icon:Texture","tab_idx"),&Tabs::get_tab_icon);
|
||||
ObjectTypeDB::bind_method(_MD("remove_tab","tab_idx"),&Tabs::remove_tab);
|
||||
ObjectTypeDB::bind_method(_MD("add_tab","title","icon:Texture"),&Tabs::add_tab);
|
||||
ObjectTypeDB::bind_method(_MD("set_tab_align","align"),&Tabs::set_tab_align);
|
||||
ObjectTypeDB::bind_method(_MD("get_tab_align"),&Tabs::get_tab_align);
|
||||
|
||||
ADD_SIGNAL(MethodInfo("tab_changed",PropertyInfo(Variant::INT,"tab")));
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE,"-1,4096,1",PROPERTY_USAGE_EDITOR), _SCS("set_current_tab"), _SCS("get_current_tab") );
|
||||
|
||||
BIND_CONSTANT( ALIGN_LEFT );
|
||||
BIND_CONSTANT( ALIGN_CENTER );
|
||||
BIND_CONSTANT( ALIGN_RIGHT );
|
||||
}
|
||||
|
||||
Tabs::Tabs() {
|
||||
|
||||
current=0;
|
||||
tab_align=ALIGN_CENTER;
|
||||
|
||||
}
|
||||
|
@ -34,6 +34,14 @@
|
||||
class Tabs : public Control {
|
||||
|
||||
OBJ_TYPE( Tabs, Control );
|
||||
public:
|
||||
|
||||
enum TabAlign {
|
||||
|
||||
ALIGN_LEFT,
|
||||
ALIGN_CENTER,
|
||||
ALIGN_RIGHT
|
||||
};
|
||||
private:
|
||||
|
||||
|
||||
@ -42,12 +50,14 @@ private:
|
||||
String text;
|
||||
Ref<Texture> icon;
|
||||
int ofs_cache;
|
||||
int size_cache;
|
||||
};
|
||||
|
||||
Vector<Tab> tabs;
|
||||
int current;
|
||||
Control *_get_tab(int idx) const;
|
||||
int _get_top_margin() const;
|
||||
TabAlign tab_align;
|
||||
|
||||
protected:
|
||||
|
||||
@ -65,16 +75,22 @@ public:
|
||||
void set_tab_icon(int p_tab,const Ref<Texture>& p_icon);
|
||||
Ref<Texture> get_tab_icon(int p_tab) const;
|
||||
|
||||
void set_tab_align(TabAlign p_align);
|
||||
TabAlign get_tab_align() const;
|
||||
|
||||
int get_tab_count() const;
|
||||
void set_current_tab(int p_current);
|
||||
int get_current_tab() const;
|
||||
|
||||
void remove_tab(int p_idx);
|
||||
|
||||
void clear_tabs();
|
||||
|
||||
Size2 get_minimum_size() const;
|
||||
|
||||
Tabs();
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(Tabs::TabAlign);
|
||||
|
||||
#endif // TABS_H
|
||||
|
@ -3323,9 +3323,32 @@ void TextEdit::_update_completion_candidates() {
|
||||
|
||||
//look for keywords first
|
||||
|
||||
bool pre_keyword=false;
|
||||
bool inquote=false;
|
||||
int first_quote=-1;
|
||||
|
||||
if (cofs>0 && l[cofs-1]==' ') {
|
||||
int c=cofs-1;
|
||||
while(c>=0) {
|
||||
if (l[c]=='"' || l[c]=='\'') {
|
||||
inquote=!inquote;
|
||||
if (first_quote==-1)
|
||||
first_quote=c;
|
||||
}
|
||||
c--;
|
||||
}
|
||||
|
||||
bool pre_keyword=false;
|
||||
bool cancel=false;
|
||||
|
||||
//print_line("inquote: "+itos(inquote)+"first quote "+itos(first_quote)+" cofs-1 "+itos(cofs-1));
|
||||
if (!inquote && first_quote==cofs-1) {
|
||||
//no completion here
|
||||
//print_line("cancel!");
|
||||
cancel=true;
|
||||
} if (inquote && first_quote!=-1) {
|
||||
|
||||
s=l.substr(first_quote,cofs-first_quote);
|
||||
//print_line("s: 1"+s);
|
||||
} else if (cofs>0 && l[cofs-1]==' ') {
|
||||
int kofs=cofs-1;
|
||||
String kw;
|
||||
while (kofs>=0 && l[kofs]==' ')
|
||||
@ -3337,7 +3360,7 @@ void TextEdit::_update_completion_candidates() {
|
||||
}
|
||||
|
||||
pre_keyword=keywords.has(kw);
|
||||
print_line("KW "+kw+"? "+itos(pre_keyword));
|
||||
//print_line("KW "+kw+"? "+itos(pre_keyword));
|
||||
|
||||
} else {
|
||||
|
||||
@ -3354,7 +3377,7 @@ void TextEdit::_update_completion_candidates() {
|
||||
|
||||
update();
|
||||
|
||||
if (!pre_keyword && s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1])))) {
|
||||
if (cancel || (!pre_keyword && s=="" && (cofs==0 || !completion_prefixes.has(String::chr(l[cofs-1]))))) {
|
||||
//none to complete, cancel
|
||||
_cancel_completion();
|
||||
return;
|
||||
@ -3421,7 +3444,16 @@ void TextEdit::query_code_comple() {
|
||||
String l = text[cursor.line];
|
||||
int ofs = CLAMP(cursor.column,0,l.length());
|
||||
|
||||
if (ofs>0 && (_is_completable(l[ofs-1]) || completion_prefixes.has(String::chr(l[ofs-1]))))
|
||||
bool inquote=false;
|
||||
|
||||
int c=ofs-1;
|
||||
while(c>=0) {
|
||||
if (l[c]=='"' || l[c]=='\'')
|
||||
inquote=!inquote;
|
||||
c--;
|
||||
}
|
||||
|
||||
if (ofs>0 && (inquote || _is_completable(l[ofs-1]) || completion_prefixes.has(String::chr(l[ofs-1]))))
|
||||
emit_signal("request_completion");
|
||||
|
||||
}
|
||||
|
@ -454,6 +454,8 @@ public:
|
||||
void set_cursor_can_exit_tree(bool p_enable);
|
||||
bool can_cursor_exit_tree() const;
|
||||
|
||||
VScrollBar *get_vscroll_bar() { return v_scroll; }
|
||||
|
||||
Tree();
|
||||
~Tree();
|
||||
|
||||
|
@ -180,6 +180,11 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
|
||||
if (flags_found["tolinear"])
|
||||
flags|=Texture::FLAG_CONVERT_TO_LINEAR;
|
||||
}
|
||||
|
||||
if (flags_found.has("mirroredrepeat")) {
|
||||
if (flags_found["mirroredrepeat"])
|
||||
flags|=Texture::FLAG_MIRRORED_REPEAT;
|
||||
}
|
||||
|
||||
if (debug_load_times)
|
||||
begtime=OS::get_singleton()->get_ticks_usec();
|
||||
|
@ -1816,6 +1816,16 @@ void Node::get_argument_options(const StringName& p_function,int p_idx,List<Stri
|
||||
Object::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
|
||||
void Node::clear_internal_tree_resource_paths() {
|
||||
|
||||
clear_internal_resource_paths();
|
||||
for(int i=0;i<data.children.size();i++) {
|
||||
data.children[i]->clear_internal_tree_resource_paths();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Node::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_name","name"),&Node::set_name);
|
||||
|
@ -290,6 +290,8 @@ public:
|
||||
|
||||
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
void clear_internal_tree_resource_paths();
|
||||
|
||||
_FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; }
|
||||
|
||||
/* CANVAS */
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 319 B |
Binary file not shown.
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 321 B |
@ -340,12 +340,12 @@ static const unsigned char scroll_grabber_hl_png[]={
|
||||
|
||||
|
||||
static const unsigned char selection_png[]={
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x11,0x12,0x2a,0x16,0x85,0x48,0x8b,0x13,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0xba,0x49,0x44,0x41,0x54,0x38,0x8d,0xed,0x93,0x31,0xa,0xc2,0x50,0x10,0x44,0xdf,0x97,0xbf,0x8a,0x3f,0x45,0xd0,0x52,0xbb,0xfc,0x63,0x88,0x88,0xa7,0xd0,0x23,0x9a,0x63,0x84,0x90,0x63,0x24,0x9d,0x9d,0x60,0x95,0x2f,0xb2,0x21,0x5a,0x18,0xb4,0x52,0x3,0x69,0x2c,0x9c,0x6e,0x8b,0x99,0xd9,0x59,0x76,0xc,0x30,0x6,0xa6,0xc0,0x4,0x18,0xd1,0xf,0x2d,0x70,0x5,0x2e,0xb6,0x23,0x2f,0x81,0x19,0x20,0x3d,0x5,0x14,0x38,0x3,0x47,0xdb,0x39,0xcf,0xd7,0xab,0xcd,0xc2,0x27,0xfe,0x20,0x22,0xe6,0x23,0x53,0xf5,0x56,0x56,0xe5,0x3e,0x2f,0x32,0x3,0x9c,0x6c,0xb7,0xb6,0xf5,0x89,0x4f,0x43,0x8,0xd4,0x21,0x7c,0xb4,0x8e,0x9c,0x33,0x3e,0xf1,0x69,0x5e,0x64,0x5b,0x60,0xf4,0xcc,0x2c,0x22,0x5f,0xc9,0x0,0x75,0x8,0x88,0xbc,0x92,0xf6,0x3d,0xda,0x5b,0xfc,0x5,0x7e,0x4a,0x40,0x55,0x89,0x9c,0xfb,0x4a,0x88,0x9c,0x43,0x55,0x9f,0xb3,0xe5,0x51,0x8c,0xa6,0xac,0xca,0x9d,0x4f,0xfc,0x21,0x8e,0xe3,0x5e,0xaf,0xc,0x34,0x40,0x6b,0x80,0x98,0x1,0x65,0x32,0xc,0xac,0xf3,0x1d,0x55,0xc6,0x3e,0x2,0xe2,0x2e,0xc9,0xc8,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x15,0x0,0x15,0x0,0x17,0xc8,0x7d,0x47,0xd1,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0x14,0x14,0x31,0x1a,0x5f,0x97,0xc4,0x56,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0xa3,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0x93,0xbd,0xa,0xc2,0x40,0x10,0x84,0xbf,0xbb,0x6c,0x72,0x8,0x1,0x51,0x4b,0xdf,0x23,0xc9,0xfb,0x57,0x12,0x9f,0x43,0xb0,0x10,0x2c,0x14,0xe4,0x92,0xcb,0xc5,0x66,0x3,0x36,0x26,0x7,0x69,0x2c,0x9c,0x6e,0x60,0x67,0xf6,0x87,0x1d,0x3,0x14,0xc0,0x6,0x70,0x80,0x25,0xd,0x11,0xf0,0xc0,0x4b,0x54,0x7c,0x4,0x76,0x40,0x9e,0x68,0xd0,0x3,0x77,0xe0,0x22,0xda,0x79,0x3f,0xf4,0x63,0x4b,0xa0,0x56,0x3e,0x7,0x8f,0x70,0xce,0x72,0x53,0x1,0x37,0xd1,0xb1,0x85,0x40,0xc3,0xc8,0xc3,0x47,0xae,0x73,0x6a,0x67,0x29,0x9,0x34,0xaa,0xb3,0x9f,0x3b,0x17,0x3e,0xf2,0x5c,0x9a,0x5d,0x6b,0x8a,0x89,0xa7,0x1e,0xed,0x2b,0xfe,0x6,0xbf,0x66,0xd0,0x39,0x4b,0xb9,0x24,0xd0,0x9a,0x6e,0xe2,0xa2,0xc1,0x8,0x8,0x2d,0x81,0xda,0x65,0x1c,0x12,0x5e,0xf9,0x4,0x54,0x40,0x34,0xc0,0x76,0x4d,0x98,0xcc,0xda,0x38,0xbf,0x1,0xae,0x5a,0x2a,0xba,0xb8,0xa1,0xb8,0x4f,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
};
|
||||
|
||||
|
||||
static const unsigned char selection_oof_png[]={
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x4c,0x0,0x4a,0x0,0x4e,0x88,0x29,0x6a,0xb6,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x10,0x15,0x32,0x22,0x9b,0x14,0x96,0x1f,0x0,0x0,0x0,0x19,0x74,0x45,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x57,0x81,0xe,0x17,0x0,0x0,0x0,0xba,0x49,0x44,0x41,0x54,0x38,0x8d,0xed,0xd3,0xb1,0x4e,0xc3,0x40,0x10,0x84,0xe1,0xef,0xc2,0x4a,0x9c,0x90,0xb,0x6a,0x9f,0xe0,0x9,0x2,0xbc,0x58,0xc2,0xcb,0xc0,0x8b,0x85,0xa4,0xa6,0x41,0x4e,0x4d,0x41,0x71,0x91,0xe,0x99,0x2,0xd7,0x76,0xa4,0x34,0x14,0x6c,0xb9,0xda,0xf9,0x47,0x2b,0xcd,0x24,0xdc,0xe0,0x16,0x1d,0xae,0x90,0xcc,0xcf,0x88,0x6f,0x7c,0xe1,0x33,0x26,0xf1,0x23,0xee,0x90,0xcf,0x4,0x54,0x7c,0xe0,0x2d,0x26,0xe7,0xfb,0x87,0xf5,0xd3,0xba,0xf4,0x65,0x13,0x11,0xb3,0x80,0xd6,0xda,0x38,0x1c,0x87,0xd7,0xfd,0x61,0x97,0xf0,0x1e,0x8,0x5c,0x97,0xbe,0x6c,0x6b,0xad,0x6a,0xad,0xb3,0xf6,0x39,0xe7,0x54,0xfa,0xb2,0xdd,0x1f,0x76,0xcf,0x88,0xd5,0xb4,0x4f,0x11,0xb1,0x28,0x86,0x5a,0xab,0x88,0x60,0x7a,0x75,0x35,0x7f,0xbe,0x3c,0xff,0x80,0xbf,0x4,0x18,0x5b,0x6b,0x72,0xce,0x8b,0x82,0x9c,0xb3,0xd6,0x1a,0xbf,0x91,0x16,0x68,0x38,0xd,0xc7,0xe1,0xa5,0xf4,0x65,0xd3,0x75,0xdd,0x59,0x51,0xc6,0x9,0x2d,0xa1,0x77,0x41,0x99,0x92,0xb,0xeb,0xfc,0x3,0xd0,0xc5,0x44,0x36,0x1d,0x79,0x84,0xde,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x15,0x0,0x15,0x0,0x17,0xc8,0x7d,0x47,0xd1,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdf,0x6,0x14,0x14,0x32,0x15,0xe4,0x5,0x8a,0x4,0x0,0x0,0x0,0x1d,0x69,0x54,0x58,0x74,0x43,0x6f,0x6d,0x6d,0x65,0x6e,0x74,0x0,0x0,0x0,0x0,0x0,0x43,0x72,0x65,0x61,0x74,0x65,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x47,0x49,0x4d,0x50,0x64,0x2e,0x65,0x7,0x0,0x0,0x0,0xa5,0x49,0x44,0x41,0x54,0x38,0xcb,0xed,0xd3,0x41,0x6a,0x2,0x51,0x10,0x4,0xd0,0xf7,0xe7,0xff,0xc1,0x30,0x4,0xe2,0x5a,0x18,0x4f,0x10,0x2,0x9e,0x29,0xe7,0xca,0x99,0x4,0xc9,0xda,0xcd,0x5c,0x20,0x8b,0x20,0x8a,0xfe,0x8c,0x9b,0x76,0xeb,0x8,0xb3,0xc9,0xc2,0x82,0xde,0x34,0x55,0xd5,0x34,0x54,0x25,0x74,0x58,0xe2,0x15,0x19,0xc9,0x7d,0x8c,0xa8,0xf8,0xc5,0x4f,0x9,0xf1,0x7,0x7a,0xbc,0x3c,0x68,0x70,0xc4,0x80,0x5d,0x89,0xcb,0x6b,0xef,0xcd,0x57,0xdd,0xd6,0x1e,0xed,0x84,0xc1,0x39,0x6f,0xf2,0xe0,0xfb,0xef,0x13,0xfb,0x82,0x82,0x45,0x88,0xf,0x31,0xf7,0xd0,0xd5,0x6d,0xed,0x73,0x9b,0x16,0x28,0x4d,0x2c,0x53,0x5c,0x9e,0x12,0xb,0x4e,0x7b,0x7b,0xb5,0x31,0x13,0x4f,0x83,0xff,0x64,0x30,0xe2,0x1c,0xbd,0x98,0x42,0x17,0xdc,0x51,0xa4,0xf0,0x82,0x53,0xde,0xe4,0x21,0xd2,0xf8,0xf6,0x50,0x94,0x39,0xe1,0x92,0xb0,0x9a,0x53,0xa6,0x34,0xb7,0xce,0x57,0x8f,0xdf,0x31,0x5b,0x17,0xde,0x59,0x7e,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
|
||||
};
|
||||
|
||||
|
||||
|
@ -510,6 +510,7 @@ float Font::draw_char(RID p_canvas_item, const Point2& p_pos, const CharType& p_
|
||||
|
||||
void Font::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("create_from_fnt","path"),&Font::create_from_fnt);
|
||||
ObjectTypeDB::bind_method(_MD("set_height","px"),&Font::set_height);
|
||||
ObjectTypeDB::bind_method(_MD("get_height"),&Font::get_height);
|
||||
|
||||
|
@ -81,6 +81,7 @@ void Texture::_bind_methods() {
|
||||
BIND_CONSTANT( FLAGS_DEFAULT );
|
||||
BIND_CONSTANT( FLAG_ANISOTROPIC_FILTER );
|
||||
BIND_CONSTANT( FLAG_CONVERT_TO_LINEAR );
|
||||
BIND_CONSTANT( FLAG_MIRRORED_REPEAT );
|
||||
|
||||
}
|
||||
|
||||
@ -181,7 +182,7 @@ void ImageTexture::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
|
||||
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "flags", PROPERTY_HINT_FLAGS,"Mipmaps,Repeat,Filter,Anisotropic,sRGB") );
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "flags", PROPERTY_HINT_FLAGS,"Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat") );
|
||||
p_list->push_back( PropertyInfo( Variant::IMAGE, "image", img_hint,String::num(lossy_storage_quality)) );
|
||||
p_list->push_back( PropertyInfo( Variant::VECTOR2, "size",PROPERTY_HINT_NONE, ""));
|
||||
p_list->push_back( PropertyInfo( Variant::INT, "storage", PROPERTY_HINT_ENUM,"Uncompressed,Compress Lossy,Compress Lossless"));
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
FLAG_CONVERT_TO_LINEAR=VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR,
|
||||
FLAG_VIDEO_SURFACE=VisualServer::TEXTURE_FLAG_VIDEO_SURFACE,
|
||||
FLAGS_DEFAULT=FLAG_MIPMAPS|FLAG_REPEAT|FLAG_FILTER,
|
||||
FLAG_MIRRORED_REPEAT=VisualServer::TEXTURE_FLAG_MIRRORED_REPEAT
|
||||
};
|
||||
|
||||
|
||||
|
@ -55,7 +55,7 @@ void register_server_types() {
|
||||
ObjectTypeDB::register_virtual_type<Physics2DDirectBodyState>();
|
||||
ObjectTypeDB::register_virtual_type<Physics2DDirectSpaceState>();
|
||||
ObjectTypeDB::register_virtual_type<Physics2DShapeQueryResult>();
|
||||
ObjectTypeDB::register_virtual_type<Physics2DTestMotionResult>();
|
||||
ObjectTypeDB::register_type<Physics2DTestMotionResult>();
|
||||
ObjectTypeDB::register_type<Physics2DShapeQueryParameters>();
|
||||
|
||||
ObjectTypeDB::register_type<PhysicsShapeQueryParameters>();
|
||||
|
@ -592,6 +592,7 @@ public:
|
||||
RID shadow_buffer;
|
||||
int shadow_buffer_size;
|
||||
float shadow_esm_mult;
|
||||
Color shadow_color;
|
||||
|
||||
|
||||
void *texture_cache; // implementation dependent
|
||||
@ -610,6 +611,7 @@ public:
|
||||
CanvasLight() {
|
||||
enabled=true;
|
||||
color=Color(1,1,1);
|
||||
shadow_color=Color(0,0,0,0);
|
||||
height=0;
|
||||
z_min=-1024;
|
||||
z_max=1024;
|
||||
|
@ -4071,6 +4071,15 @@ void VisualServerRaster::canvas_light_set_shadow_esm_multiplier(RID p_light, flo
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_shadow_color(RID p_light, const Color& p_color) {
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->shadow_color=p_color;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/****** CANVAS LIGHT OCCLUDER ******/
|
||||
|
||||
RID VisualServerRaster::canvas_light_occluder_create() {
|
||||
|
@ -1180,6 +1180,8 @@ public:
|
||||
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
|
||||
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
|
||||
virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier);
|
||||
virtual void canvas_light_set_shadow_color(RID p_light, const Color& p_color);
|
||||
|
||||
|
||||
|
||||
virtual RID canvas_light_occluder_create();
|
||||
|
@ -626,6 +626,8 @@ public:
|
||||
FUNC2(canvas_light_set_shadow_enabled,RID,bool);
|
||||
FUNC2(canvas_light_set_shadow_buffer_size,RID,int);
|
||||
FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float);
|
||||
FUNC2(canvas_light_set_shadow_color,RID,const Color&);
|
||||
|
||||
|
||||
|
||||
/* CANVAS OCCLUDER */
|
||||
|
@ -104,6 +104,7 @@ public:
|
||||
TEXTURE_FLAG_FILTER=4, /// Create texure with linear (or available) filter
|
||||
TEXTURE_FLAG_ANISOTROPIC_FILTER=8,
|
||||
TEXTURE_FLAG_CONVERT_TO_LINEAR=16,
|
||||
TEXTURE_FLAG_MIRRORED_REPEAT=32, /// Repeat texture, with alternate sections mirrored
|
||||
TEXTURE_FLAG_CUBEMAP=2048,
|
||||
TEXTURE_FLAG_VIDEO_SURFACE=4096,
|
||||
TEXTURE_FLAGS_DEFAULT=TEXTURE_FLAG_REPEAT|TEXTURE_FLAG_MIPMAPS|TEXTURE_FLAG_FILTER
|
||||
@ -1032,6 +1033,7 @@ public:
|
||||
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0;
|
||||
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0;
|
||||
virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier)=0;
|
||||
virtual void canvas_light_set_shadow_color(RID p_light, const Color& p_color)=0;
|
||||
|
||||
|
||||
|
||||
|
@ -3319,7 +3319,8 @@ void AnimationKeyEditor::_insert_delay() {
|
||||
void AnimationKeyEditor::_step_changed(float p_len) {
|
||||
|
||||
updating=true;
|
||||
animation->set_step(p_len);
|
||||
if (!animation.is_null())
|
||||
animation->set_step(p_len);
|
||||
updating=false;
|
||||
}
|
||||
|
||||
|
@ -530,7 +530,7 @@ void ConnectionsDialog::ok_pressed() {
|
||||
get_ok()->set_disabled(true);
|
||||
return;
|
||||
}
|
||||
if (item->get_parent()==tree->get_root()) {
|
||||
if (item->get_parent()==tree->get_root() || item->get_parent()->get_parent()==tree->get_root()) {
|
||||
//a signal - connect
|
||||
String signal=item->get_metadata(0).operator Dictionary()["name"];
|
||||
String signalname=signal;
|
||||
@ -632,74 +632,130 @@ void ConnectionsDialog::update_tree() {
|
||||
node->get_signal_list(&node_signals);
|
||||
|
||||
//node_signals.sort_custom<_ConnectionsDialogMethodInfoSort>();
|
||||
bool did_script=false;
|
||||
StringName base = node->get_type();
|
||||
|
||||
for(List<MethodInfo>::Element *E=node_signals.front();E;E=E->next()) {
|
||||
|
||||
while(base) {
|
||||
|
||||
MethodInfo &mi =E->get();
|
||||
List<MethodInfo> node_signals;
|
||||
Ref<Texture> icon;
|
||||
String name;
|
||||
|
||||
String signaldesc;
|
||||
signaldesc=mi.name+"(";
|
||||
StringArray argnames;
|
||||
if (mi.arguments.size()) {
|
||||
signaldesc+=" ";
|
||||
for(int i=0;i<mi.arguments.size();i++) {
|
||||
if (!did_script) {
|
||||
|
||||
PropertyInfo &pi = mi.arguments[i];
|
||||
|
||||
if (i>0)
|
||||
signaldesc+=", ";
|
||||
signaldesc+=Variant::get_type_name(pi.type)+" "+(pi.name==""?String("arg "+itos(i)):pi.name);
|
||||
argnames.push_back(pi.name);
|
||||
Ref<Script> scr = node->get_script();
|
||||
if (scr.is_valid()) {
|
||||
scr->get_script_signal_list(&node_signals);
|
||||
if (scr->get_path().is_resource_file())
|
||||
name=scr->get_path().get_file();
|
||||
else
|
||||
name=scr->get_type();
|
||||
|
||||
if (has_icon(scr->get_type(),"EditorIcons")) {
|
||||
icon=get_icon(scr->get_type(),"EditorIcons");
|
||||
}
|
||||
}
|
||||
signaldesc+=" ";
|
||||
|
||||
} else {
|
||||
|
||||
ObjectTypeDB::get_signal_list(base,&node_signals,true);
|
||||
if (has_icon(base,"EditorIcons")) {
|
||||
icon=get_icon(base,"EditorIcons");
|
||||
}
|
||||
name=base;
|
||||
}
|
||||
|
||||
signaldesc+=")";
|
||||
|
||||
TreeItem *item=tree->create_item(root);
|
||||
item->set_text(0,signaldesc);
|
||||
Dictionary sinfo;
|
||||
sinfo["name"]=mi.name;
|
||||
sinfo["args"]=argnames;
|
||||
item->set_metadata(0,sinfo);
|
||||
item->set_icon(0,get_icon("Signal","EditorIcons"));
|
||||
|
||||
List<Object::Connection> connections;
|
||||
node->get_signal_connection_list(mi.name,&connections);
|
||||
TreeItem *pitem = NULL;
|
||||
|
||||
for(List<Object::Connection>::Element *F=connections.front();F;F=F->next()) {
|
||||
if (node_signals.size()) {
|
||||
pitem=tree->create_item(root);
|
||||
pitem->set_text(0,name);
|
||||
pitem->set_icon(0,icon);
|
||||
pitem->set_selectable(0,false);
|
||||
pitem->set_editable(0,false);
|
||||
pitem->set_custom_bg_color(0,get_color("prop_subsection","Editor"));
|
||||
node_signals.sort();
|
||||
}
|
||||
|
||||
Object::Connection&c = F->get();
|
||||
if (!(c.flags&CONNECT_PERSIST))
|
||||
continue;
|
||||
for(List<MethodInfo>::Element *E=node_signals.front();E;E=E->next()) {
|
||||
|
||||
Node *target = c.target->cast_to<Node>();
|
||||
if (!target)
|
||||
continue;
|
||||
|
||||
String path = String(node->get_path_to(target))+" :: "+c.method+"()";
|
||||
if (c.flags&CONNECT_DEFERRED)
|
||||
path+=" (deferred)";
|
||||
if (c.binds.size()) {
|
||||
MethodInfo &mi =E->get();
|
||||
|
||||
path+=" binds( ";
|
||||
for(int i=0;i<c.binds.size();i++) {
|
||||
String signaldesc;
|
||||
signaldesc=mi.name+"(";
|
||||
StringArray argnames;
|
||||
if (mi.arguments.size()) {
|
||||
signaldesc+=" ";
|
||||
for(int i=0;i<mi.arguments.size();i++) {
|
||||
|
||||
PropertyInfo &pi = mi.arguments[i];
|
||||
|
||||
if (i>0)
|
||||
path+=", ";
|
||||
path+=c.binds[i].operator String();
|
||||
signaldesc+=", ";
|
||||
String tname="var";
|
||||
if (pi.type!=Variant::NIL) {
|
||||
tname=Variant::get_type_name(pi.type);
|
||||
}
|
||||
signaldesc+=tname+" "+(pi.name==""?String("arg "+itos(i)):pi.name);
|
||||
argnames.push_back(pi.name);
|
||||
|
||||
}
|
||||
path+=" )";
|
||||
signaldesc+=" ";
|
||||
}
|
||||
|
||||
TreeItem *item2=tree->create_item(item);
|
||||
item2->set_text(0,path);
|
||||
item2->set_metadata(0,c);
|
||||
item2->set_icon(0,get_icon("Slot","EditorIcons"));
|
||||
signaldesc+=")";
|
||||
|
||||
TreeItem *item=tree->create_item(pitem);
|
||||
item->set_text(0,signaldesc);
|
||||
Dictionary sinfo;
|
||||
sinfo["name"]=mi.name;
|
||||
sinfo["args"]=argnames;
|
||||
item->set_metadata(0,sinfo);
|
||||
item->set_icon(0,get_icon("Signal","EditorIcons"));
|
||||
|
||||
List<Object::Connection> connections;
|
||||
node->get_signal_connection_list(mi.name,&connections);
|
||||
|
||||
for(List<Object::Connection>::Element *F=connections.front();F;F=F->next()) {
|
||||
|
||||
Object::Connection&c = F->get();
|
||||
if (!(c.flags&CONNECT_PERSIST))
|
||||
continue;
|
||||
|
||||
Node *target = c.target->cast_to<Node>();
|
||||
if (!target)
|
||||
continue;
|
||||
|
||||
String path = String(node->get_path_to(target))+" :: "+c.method+"()";
|
||||
if (c.flags&CONNECT_DEFERRED)
|
||||
path+=" (deferred)";
|
||||
if (c.binds.size()) {
|
||||
|
||||
path+=" binds( ";
|
||||
for(int i=0;i<c.binds.size();i++) {
|
||||
|
||||
if (i>0)
|
||||
path+=", ";
|
||||
path+=c.binds[i].operator String();
|
||||
}
|
||||
path+=" )";
|
||||
}
|
||||
|
||||
TreeItem *item2=tree->create_item(item);
|
||||
item2->set_text(0,path);
|
||||
item2->set_metadata(0,c);
|
||||
item2->set_icon(0,get_icon("Slot","EditorIcons"));
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (!did_script) {
|
||||
did_script=true;
|
||||
} else {
|
||||
base=ObjectTypeDB::type_inherits_from(base);
|
||||
}
|
||||
}
|
||||
|
||||
@ -722,7 +778,7 @@ void ConnectionsDialog::_something_selected() {
|
||||
get_ok()->set_text("Connect..");
|
||||
get_ok()->set_disabled(true);
|
||||
|
||||
} else if (item->get_parent()==tree->get_root()) {
|
||||
} else if (item->get_parent()==tree->get_root() || item->get_parent()->get_parent()==tree->get_root()) {
|
||||
//a signal - connect
|
||||
get_ok()->set_text("Connect..");
|
||||
get_ok()->set_disabled(false);
|
||||
|
@ -424,9 +424,182 @@ void EditorData::remove_custom_type(const String& p_type){
|
||||
|
||||
}
|
||||
|
||||
int EditorData::add_edited_scene(int p_at_pos) {
|
||||
|
||||
if (p_at_pos<0)
|
||||
p_at_pos=edited_scene.size();
|
||||
EditedScene es;
|
||||
es.root=NULL;
|
||||
es.history_current=-1;
|
||||
es.version=0;
|
||||
|
||||
if (p_at_pos==edited_scene.size())
|
||||
edited_scene.push_back(es);
|
||||
else
|
||||
edited_scene.insert(p_at_pos,es);
|
||||
|
||||
if (current_edited_scene<0)
|
||||
current_edited_scene=0;
|
||||
return p_at_pos;
|
||||
}
|
||||
|
||||
void EditorData::move_edited_scene_index(int p_idx,int p_to_idx){
|
||||
|
||||
ERR_FAIL_INDEX(p_idx,edited_scene.size());
|
||||
ERR_FAIL_INDEX(p_to_idx,edited_scene.size());
|
||||
SWAP(edited_scene[p_idx],edited_scene[p_to_idx]);
|
||||
}
|
||||
void EditorData::remove_scene(int p_idx){
|
||||
ERR_FAIL_INDEX(p_idx,edited_scene.size());
|
||||
if (edited_scene[p_idx].root)
|
||||
memdelete(edited_scene[p_idx].root);
|
||||
|
||||
if (current_edited_scene>p_idx)
|
||||
current_edited_scene--;
|
||||
else if (current_edited_scene==p_idx && current_edited_scene>0) {
|
||||
current_edited_scene--;
|
||||
}
|
||||
|
||||
edited_scene.remove(p_idx);
|
||||
|
||||
}
|
||||
int EditorData::get_edited_scene() const {
|
||||
|
||||
return current_edited_scene;
|
||||
}
|
||||
void EditorData::set_edited_scene(int p_idx){
|
||||
|
||||
ERR_FAIL_INDEX(p_idx,edited_scene.size());
|
||||
current_edited_scene=p_idx;
|
||||
//swap
|
||||
}
|
||||
Node* EditorData::get_edited_scene_root(){
|
||||
|
||||
ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),NULL);
|
||||
|
||||
return edited_scene[current_edited_scene].root;
|
||||
}
|
||||
void EditorData::set_edited_scene_root(Node* p_root) {
|
||||
|
||||
ERR_FAIL_INDEX(current_edited_scene,edited_scene.size());
|
||||
edited_scene[current_edited_scene].root=p_root;
|
||||
}
|
||||
|
||||
int EditorData::get_edited_scene_count() const {
|
||||
|
||||
return edited_scene.size();
|
||||
}
|
||||
|
||||
void EditorData::set_edited_scene_version(uint64_t version) {
|
||||
ERR_FAIL_INDEX(current_edited_scene,edited_scene.size());
|
||||
edited_scene[current_edited_scene].version=version;
|
||||
|
||||
}
|
||||
|
||||
uint64_t EditorData::get_edited_scene_version() const{
|
||||
|
||||
ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),0);
|
||||
return edited_scene[current_edited_scene].version;
|
||||
|
||||
}
|
||||
uint64_t EditorData::get_scene_version(int p_idx) const{
|
||||
ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),false);
|
||||
return edited_scene[p_idx].version;
|
||||
}
|
||||
|
||||
String EditorData::get_scene_title(int p_idx) const {
|
||||
ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String());
|
||||
if (!edited_scene[p_idx].root)
|
||||
return "[empty]";
|
||||
if (edited_scene[p_idx].root->get_filename()=="")
|
||||
return "[unsaved]";
|
||||
return edited_scene[p_idx].root->get_filename().get_file();
|
||||
}
|
||||
|
||||
|
||||
String EditorData::get_scene_path(int p_idx) const {
|
||||
|
||||
ERR_FAIL_INDEX_V(p_idx,edited_scene.size(),String());
|
||||
|
||||
if (!edited_scene[p_idx].root)
|
||||
return "";
|
||||
return edited_scene[p_idx].root->get_filename();
|
||||
|
||||
}
|
||||
|
||||
void EditorData::save_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history, const Dictionary& p_custom) {
|
||||
|
||||
ERR_FAIL_INDEX(current_edited_scene,edited_scene.size());
|
||||
|
||||
EditedScene &es=edited_scene[current_edited_scene];
|
||||
es.selection = p_selection->get_selected_node_list();
|
||||
es.history_current=p_history->current;
|
||||
es.history_stored=p_history->history;
|
||||
es.editor_states=get_editor_states();
|
||||
es.custom_state=p_custom;
|
||||
|
||||
}
|
||||
|
||||
Dictionary EditorData::restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history) {
|
||||
ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Dictionary());
|
||||
|
||||
EditedScene &es=edited_scene[current_edited_scene];
|
||||
|
||||
p_history->current=es.history_current;
|
||||
p_history->history=es.history_stored;
|
||||
|
||||
|
||||
p_selection->clear();
|
||||
for(List<Node*>::Element *E=es.selection.front();E;E=E->next()) {
|
||||
p_selection->add_node(E->get());
|
||||
}
|
||||
set_editor_states(es.editor_states);
|
||||
|
||||
return es.custom_state;
|
||||
}
|
||||
|
||||
|
||||
void EditorData::set_edited_scene_import_metadata(Ref<ResourceImportMetadata> p_mdata) {
|
||||
|
||||
ERR_FAIL_INDEX(current_edited_scene,edited_scene.size());
|
||||
edited_scene[current_edited_scene].medatata=p_mdata;
|
||||
|
||||
}
|
||||
|
||||
Ref<ResourceImportMetadata> EditorData::get_edited_scene_import_metadata() const{
|
||||
|
||||
ERR_FAIL_INDEX_V(current_edited_scene,edited_scene.size(),Ref<ResourceImportMetadata>());
|
||||
return edited_scene[current_edited_scene].medatata;
|
||||
}
|
||||
|
||||
void EditorData::clear_edited_scenes() {
|
||||
|
||||
for(int i=0;i<edited_scene.size();i++) {
|
||||
if (edited_scene[i].root) {
|
||||
memdelete( edited_scene[i].root );
|
||||
}
|
||||
}
|
||||
edited_scene.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EditorData::set_plugin_window_layout(Ref<ConfigFile> p_layout) {
|
||||
for(int i=0;i<editor_plugins.size();i++) {
|
||||
editor_plugins[i]->set_window_layout(p_layout);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorData::get_plugin_window_layout(Ref<ConfigFile> p_layout) {
|
||||
for(int i=0;i<editor_plugins.size();i++) {
|
||||
editor_plugins[i]->get_window_layout(p_layout);
|
||||
}
|
||||
}
|
||||
|
||||
EditorData::EditorData() {
|
||||
|
||||
current_edited_scene=-1;
|
||||
|
||||
// load_imported_scenes_from_globals();
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ class EditorHistory {
|
||||
Vector<Obj> path;
|
||||
int level;
|
||||
};
|
||||
friend class EditorData;
|
||||
|
||||
Vector<History> history;
|
||||
int current;
|
||||
@ -91,6 +92,8 @@ public:
|
||||
EditorHistory();
|
||||
};
|
||||
|
||||
class EditorSelection;
|
||||
|
||||
class EditorData {
|
||||
|
||||
public:
|
||||
@ -117,6 +120,21 @@ private:
|
||||
|
||||
void _cleanup_history();
|
||||
|
||||
struct EditedScene {
|
||||
Node* root;
|
||||
Dictionary editor_states;
|
||||
Ref<ResourceImportMetadata> medatata;
|
||||
List<Node*> selection;
|
||||
Vector<EditorHistory::History> history_stored;
|
||||
int history_current;
|
||||
Dictionary custom_state;
|
||||
uint64_t version;
|
||||
|
||||
|
||||
};
|
||||
|
||||
Vector<EditedScene> edited_scene;
|
||||
int current_edited_scene;
|
||||
|
||||
public:
|
||||
|
||||
@ -146,6 +164,32 @@ public:
|
||||
void remove_custom_type(const String& p_type);
|
||||
const Map<String,Vector<CustomType> >& get_custom_types() const { return custom_types; }
|
||||
|
||||
|
||||
int add_edited_scene(int p_at_pos);
|
||||
void move_edited_scene_index(int p_idx,int p_to_idx);
|
||||
void remove_scene(int p_idx);
|
||||
void set_edited_scene(int p_idx);
|
||||
void set_edited_scene_root(Node* p_root);
|
||||
void set_edited_scene_import_metadata(Ref<ResourceImportMetadata> p_mdata);
|
||||
Ref<ResourceImportMetadata> get_edited_scene_import_metadata() const;
|
||||
int get_edited_scene() const;
|
||||
Node* get_edited_scene_root();
|
||||
int get_edited_scene_count() const;
|
||||
String get_scene_title(int p_idx) const;
|
||||
String get_scene_path(int p_idx) const;
|
||||
void set_edited_scene_version(uint64_t version);
|
||||
uint64_t get_edited_scene_version() const;
|
||||
uint64_t get_scene_version(int p_idx) const;
|
||||
void clear_edited_scenes();
|
||||
|
||||
|
||||
void set_plugin_window_layout(Ref<ConfigFile> p_layout);
|
||||
void get_plugin_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
||||
void save_edited_scene_state(EditorSelection *p_selection,EditorHistory *p_history,const Dictionary& p_custom);
|
||||
Dictionary restore_edited_scene_state(EditorSelection *p_selection, EditorHistory *p_history);
|
||||
|
||||
|
||||
EditorData();
|
||||
};
|
||||
|
||||
|
@ -92,6 +92,7 @@
|
||||
#include "plugins/navigation_polygon_editor_plugin.h"
|
||||
#include "plugins/light_occluder_2d_editor_plugin.h"
|
||||
#include "plugins/color_ramp_editor_plugin.h"
|
||||
#include "plugins/collision_shape_2d_editor_plugin.h"
|
||||
// end
|
||||
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
|
||||
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
|
||||
@ -105,11 +106,24 @@
|
||||
|
||||
EditorNode *EditorNode::singleton=NULL;
|
||||
|
||||
void EditorNode::_update_scene_tabs() {
|
||||
|
||||
scene_tabs->clear_tabs();
|
||||
for(int i=0;i<editor_data.get_edited_scene_count();i++) {
|
||||
int current = editor_data.get_edited_scene();
|
||||
bool unsaved = (i==current)?saved_version!=editor_data.get_undo_redo().get_version():editor_data.get_scene_version(i)!=0;
|
||||
scene_tabs->add_tab(editor_data.get_scene_title(i)+(unsaved?"(*)":""));
|
||||
}
|
||||
|
||||
scene_tabs->set_current_tab(editor_data.get_edited_scene());
|
||||
|
||||
}
|
||||
|
||||
void EditorNode::_update_title() {
|
||||
|
||||
String appname = Globals::get_singleton()->get("application/name");
|
||||
String title = appname.empty()?String(VERSION_FULL_NAME):String(_MKSTR(VERSION_NAME) + String(" - ") + appname);
|
||||
String edited = edited_scene?edited_scene->get_filename():String();
|
||||
String edited = editor_data.get_edited_scene_root()?editor_data.get_edited_scene_root()->get_filename():String();
|
||||
if (!edited.empty())
|
||||
title+=" - " + String(edited.get_file());
|
||||
if (unsaved_cache)
|
||||
@ -174,6 +188,11 @@ void EditorNode::_notification(int p_what) {
|
||||
_update_title();
|
||||
}
|
||||
|
||||
if (last_checked_version!=editor_data.get_undo_redo().get_version()) {
|
||||
_update_scene_tabs();
|
||||
last_checked_version=editor_data.get_undo_redo().get_version();
|
||||
}
|
||||
|
||||
//get_root_node()->set_rect(viewport->get_global_rect());
|
||||
|
||||
//update the circle
|
||||
@ -231,6 +250,13 @@ void EditorNode::_notification(int p_what) {
|
||||
|
||||
//import_monitor->scan_changes();
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
|
||||
|
||||
editor_data.clear_edited_scenes();
|
||||
|
||||
}
|
||||
if (p_what==NOTIFICATION_READY) {
|
||||
|
||||
VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport(),true);
|
||||
@ -468,7 +494,7 @@ void EditorNode::_dialog_display_file_error(String p_file,Error p_error) {
|
||||
|
||||
void EditorNode::_get_scene_metadata() {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene)
|
||||
return;
|
||||
@ -495,7 +521,7 @@ void EditorNode::_get_scene_metadata() {
|
||||
|
||||
void EditorNode::_set_scene_metadata() {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene)
|
||||
return;
|
||||
@ -718,7 +744,7 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed,
|
||||
for(int i=0;i<scene->get_child_count();i++) {
|
||||
|
||||
Node *n = scene->get_child(i);
|
||||
if (n->get_owner()!=edited_scene)
|
||||
if (n->get_owner()!=editor_data.get_edited_scene_root())
|
||||
continue;
|
||||
_save_edited_subresources(n,processed,flags);
|
||||
}
|
||||
@ -727,7 +753,7 @@ void EditorNode::_save_edited_subresources(Node* scene,Map<RES,bool>& processed,
|
||||
|
||||
void EditorNode::_find_node_types(Node* p_node, int&count_2d, int&count_3d) {
|
||||
|
||||
if (p_node->is_type("Viewport") || (p_node!=get_edited_scene() && p_node->get_owner()!=get_edited_scene()))
|
||||
if (p_node->is_type("Viewport") || (p_node!=editor_data.get_edited_scene_root() && p_node->get_owner()!=editor_data.get_edited_scene_root()))
|
||||
return;
|
||||
|
||||
if (p_node->is_type("CanvasItem"))
|
||||
@ -748,7 +774,7 @@ void EditorNode::_save_scene_with_preview(String p_file) {
|
||||
|
||||
EditorProgress save("save","Saving Scene",4);
|
||||
save.step("Analyzing",0);
|
||||
_find_node_types(get_edited_scene(),c2d,c3d);
|
||||
_find_node_types(editor_data.get_edited_scene_root(),c2d,c3d);
|
||||
|
||||
RID viewport;
|
||||
bool is2d;
|
||||
@ -799,11 +825,11 @@ void EditorNode::_save_scene_with_preview(String p_file) {
|
||||
img.save_png(pfile);
|
||||
Vector<uint8_t> imgdata = FileAccess::get_file_as_array(pfile);
|
||||
|
||||
print_line("img data is "+itos(imgdata.size()));
|
||||
//print_line("img data is "+itos(imgdata.size()));
|
||||
|
||||
if (scene_import_metadata.is_null())
|
||||
scene_import_metadata = Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) );
|
||||
scene_import_metadata->set_option("thumbnail",imgdata);
|
||||
if (editor_data.get_edited_scene_import_metadata().is_null())
|
||||
editor_data.set_edited_scene_import_metadata(Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ) );
|
||||
editor_data.get_edited_scene_import_metadata()->set_option("thumbnail",imgdata);
|
||||
|
||||
//tamanio tel thumbnail
|
||||
if (screen!=-1) {
|
||||
@ -817,7 +843,7 @@ void EditorNode::_save_scene_with_preview(String p_file) {
|
||||
|
||||
void EditorNode::_save_scene(String p_file) {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene) {
|
||||
|
||||
@ -851,7 +877,7 @@ void EditorNode::_save_scene(String p_file) {
|
||||
return;
|
||||
}
|
||||
|
||||
sdata->set_import_metadata(scene_import_metadata);
|
||||
sdata->set_import_metadata(editor_data.get_edited_scene_import_metadata());
|
||||
int flg=0;
|
||||
if (EditorSettings::get_singleton()->get("on_save/compress_binary_resources"))
|
||||
flg|=ResourceSaver::FLAG_COMPRESS;
|
||||
@ -867,7 +893,7 @@ void EditorNode::_save_scene(String p_file) {
|
||||
if (err==OK) {
|
||||
scene->set_filename( Globals::get_singleton()->localize_path(p_file) );
|
||||
//EditorFileSystem::get_singleton()->update_file(p_file,sdata->get_type());
|
||||
saved_version=editor_data.get_undo_redo().get_version();
|
||||
set_current_version(editor_data.get_undo_redo().get_version());
|
||||
_update_title();
|
||||
} else {
|
||||
|
||||
@ -1055,7 +1081,7 @@ void EditorNode::_dialog_action(String p_file) {
|
||||
Node *base = selection.front()->get();
|
||||
|
||||
Map<Node*,Node*> reown;
|
||||
reown[get_edited_scene()]=base;
|
||||
reown[editor_data.get_edited_scene_root()]=base;
|
||||
Node *copy = base->duplicate_and_reown(reown);
|
||||
if (copy) {
|
||||
|
||||
@ -1150,7 +1176,7 @@ void EditorNode::_dialog_action(String p_file) {
|
||||
ml = Ref<MeshLibrary>( memnew( MeshLibrary ));
|
||||
}
|
||||
|
||||
MeshLibraryEditor::update_library_file(edited_scene,ml,true);
|
||||
MeshLibraryEditor::update_library_file(editor_data.get_edited_scene_root(),ml,true);
|
||||
|
||||
Error err = ResourceSaver::save(p_file,ml);
|
||||
if (err) {
|
||||
@ -1184,7 +1210,7 @@ void EditorNode::_dialog_action(String p_file) {
|
||||
ml = Ref<TileSet>( memnew( TileSet ));
|
||||
}
|
||||
|
||||
TileSetEditor::update_library_file(edited_scene,ml,true);
|
||||
TileSetEditor::update_library_file(editor_data.get_edited_scene_root(),ml,true);
|
||||
|
||||
Error err = ResourceSaver::save(p_file,ml);
|
||||
if (err) {
|
||||
@ -1325,15 +1351,15 @@ void EditorNode::_property_editor_back() {
|
||||
|
||||
void EditorNode::_imported(Node *p_node) {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
set_edited_scene(p_node);
|
||||
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
// add_edited_scene(p_node);
|
||||
/*
|
||||
if (scene) {
|
||||
String path = scene->get_filename();
|
||||
p_node->set_filename(path);
|
||||
memdelete(scene);
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
@ -1408,17 +1434,22 @@ void EditorNode::_edit_current() {
|
||||
if (main_plugin!=editor_plugin_screen) {
|
||||
|
||||
// update screen main_plugin
|
||||
if (editor_plugin_screen)
|
||||
editor_plugin_screen->make_visible(false);
|
||||
editor_plugin_screen=main_plugin;
|
||||
editor_plugin_screen->edit(current_obj);
|
||||
editor_plugin_screen->make_visible(true);
|
||||
|
||||
if (!changing_scene) {
|
||||
|
||||
if (editor_plugin_screen)
|
||||
editor_plugin_screen->make_visible(false);
|
||||
editor_plugin_screen=main_plugin;
|
||||
editor_plugin_screen->edit(current_obj);
|
||||
|
||||
editor_plugin_screen->make_visible(true);
|
||||
|
||||
|
||||
for(int i=0;i<editor_table.size();i++) {
|
||||
if (editor_table[i]==main_plugin) {
|
||||
main_editor_tabs->set_current_tab(i);
|
||||
break;
|
||||
for(int i=0;i<editor_table.size();i++) {
|
||||
if (editor_table[i]==main_plugin) {
|
||||
main_editor_tabs->set_current_tab(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1527,10 +1558,10 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
|
||||
|
||||
|
||||
|
||||
if (p_current || (edited_scene && p_custom==edited_scene->get_filename())) {
|
||||
if (p_current || (editor_data.get_edited_scene_root() && p_custom==editor_data.get_edited_scene_root()->get_filename())) {
|
||||
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene) {
|
||||
|
||||
@ -1592,7 +1623,7 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
|
||||
|
||||
if (unsaved_cache) {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (scene) { //only autosave if there is a scene obviously
|
||||
|
||||
@ -1644,8 +1675,8 @@ void EditorNode::_run(bool p_current,const String& p_custom) {
|
||||
|
||||
void EditorNode::_cleanup_scene() {
|
||||
|
||||
|
||||
Node *scene = edited_scene;
|
||||
#if 0
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
editor_selection->clear();
|
||||
editor_data.clear_editor_states();
|
||||
editor_history.clear();
|
||||
@ -1654,7 +1685,7 @@ void EditorNode::_cleanup_scene() {
|
||||
property_editor->edit(NULL);
|
||||
resources_dock->cleanup();
|
||||
scene_import_metadata.unref();
|
||||
set_edited_scene(NULL);
|
||||
//set_edited_scene(NULL);
|
||||
if (scene) {
|
||||
if (scene->get_filename()!="") {
|
||||
previous_scenes.push_back(scene->get_filename());
|
||||
@ -1680,7 +1711,7 @@ void EditorNode::_cleanup_scene() {
|
||||
}
|
||||
|
||||
_update_title();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
@ -1693,16 +1724,20 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
switch( p_option ) {
|
||||
case FILE_NEW_SCENE: {
|
||||
|
||||
/*
|
||||
if (!p_confirmed) {
|
||||
confirmation->get_ok()->set_text("Yes");
|
||||
//confirmation->get_cancel()->show();
|
||||
confirmation->set_text("Start a New Scene? (Current will be lost)");
|
||||
confirmation->popup_centered_minsize();
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
_cleanup_scene();
|
||||
int idx = editor_data.add_edited_scene(-1);
|
||||
_scene_tab_changed(idx);
|
||||
|
||||
//_cleanup_scene();
|
||||
|
||||
|
||||
} break;
|
||||
@ -1722,7 +1757,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
|
||||
//file->set_current_path(current_path);
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
if (scene) {
|
||||
file->set_current_path(scene->get_filename());
|
||||
};
|
||||
@ -1754,11 +1789,26 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
opening_prev=true;
|
||||
open_request(previous_scenes.back()->get());
|
||||
|
||||
} break;
|
||||
case FILE_CLOSE: {
|
||||
|
||||
if (!p_confirmed) {
|
||||
confirmation->get_ok()->set_text("Yes");
|
||||
//confirmation->get_cancel()->show();
|
||||
confirmation->set_text("Close scene? (Unsaved changes will be lost)");
|
||||
confirmation->popup_centered_minsize();
|
||||
break;
|
||||
}
|
||||
|
||||
_remove_edited_scene();
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
case FILE_SAVE_SCENE: {
|
||||
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
if (scene && scene->get_filename()!="") {
|
||||
|
||||
//_save_scene(scene->get_filename());
|
||||
@ -1769,7 +1819,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
};
|
||||
case FILE_SAVE_AS_SCENE: {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene) {
|
||||
|
||||
@ -1831,7 +1881,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
case FILE_DUMP_STRINGS: {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene) {
|
||||
|
||||
@ -1875,7 +1925,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
case FILE_SAVE_SUBSCENE: {
|
||||
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (!scene) {
|
||||
|
||||
@ -1902,7 +1952,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
Node *tocopy = selection.front()->get();
|
||||
|
||||
if (tocopy!=edited_scene && tocopy->get_filename()!="") {
|
||||
if (tocopy!=editor_data.get_edited_scene_root() && tocopy->get_filename()!="") {
|
||||
|
||||
|
||||
current_option=-1;
|
||||
@ -1936,7 +1986,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
file->set_title("Save Sub-Scene As..");
|
||||
} break;
|
||||
case FILE_SAVE_OPTIMIZED: {
|
||||
Node *scene = edited_scene;
|
||||
Node *scene = editor_data.get_edited_scene_root();
|
||||
#if 0
|
||||
if (!scene) {
|
||||
|
||||
@ -1998,7 +2048,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
case FILE_EXPORT_MESH_LIBRARY: {
|
||||
|
||||
if (!edited_scene) {
|
||||
if (!editor_data.get_edited_scene_root()) {
|
||||
|
||||
current_option=-1;
|
||||
//confirmation->get_cancel()->hide();
|
||||
@ -2043,7 +2093,7 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
|
||||
|
||||
//import_subscene->popup_centered_ratio();
|
||||
|
||||
if (!edited_scene) {
|
||||
if (!editor_data.get_edited_scene_root()) {
|
||||
|
||||
current_option=-1;
|
||||
//accept->get_cancel()->hide();
|
||||
@ -2569,30 +2619,54 @@ void EditorNode::remove_editor_import_plugin(const Ref<EditorImportPlugin>& p_ed
|
||||
_rebuild_import_menu();
|
||||
}
|
||||
|
||||
void EditorNode::_remove_edited_scene() {
|
||||
int new_index = editor_data.get_edited_scene();
|
||||
int old_index=new_index;
|
||||
|
||||
if (new_index>0) {
|
||||
new_index=new_index-1;
|
||||
} else if (editor_data.get_edited_scene_count()>1) {
|
||||
new_index=1;
|
||||
} else {
|
||||
editor_data.add_edited_scene(-1);
|
||||
new_index=1;
|
||||
}
|
||||
|
||||
_scene_tab_changed(new_index);
|
||||
editor_data.remove_scene(old_index);
|
||||
editor_data.get_undo_redo().clear_history();
|
||||
_update_title();
|
||||
_update_scene_tabs();
|
||||
|
||||
if (editor_data.get_edited_scene_count()==1) {
|
||||
//make new scene appear saved
|
||||
set_current_version(editor_data.get_undo_redo().get_version());
|
||||
unsaved_cache=false;
|
||||
}
|
||||
}
|
||||
void EditorNode::set_edited_scene(Node *p_scene) {
|
||||
|
||||
if (edited_scene) {
|
||||
if (edited_scene->get_parent()==scene_root)
|
||||
scene_root->remove_child(edited_scene);
|
||||
if (get_editor_data().get_edited_scene_root()) {
|
||||
if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root)
|
||||
scene_root->remove_child(get_editor_data().get_edited_scene_root());
|
||||
animation_editor->set_root(NULL);
|
||||
}
|
||||
edited_scene=p_scene;
|
||||
if (edited_scene && edited_scene->cast_to<Popup>())
|
||||
edited_scene->cast_to<Popup>()->show(); //show popups
|
||||
scene_tree_dock->set_edited_scene(edited_scene);
|
||||
get_editor_data().set_edited_scene_root(p_scene);
|
||||
|
||||
if (p_scene && p_scene->cast_to<Popup>())
|
||||
p_scene->cast_to<Popup>()->show(); //show popups
|
||||
scene_tree_dock->set_edited_scene(p_scene);
|
||||
if (get_tree())
|
||||
get_tree()->set_edited_scene_root(edited_scene);
|
||||
get_tree()->set_edited_scene_root(p_scene);
|
||||
|
||||
if (edited_scene) {
|
||||
if (p_scene) {
|
||||
if (p_scene->get_parent()!=scene_root)
|
||||
scene_root->add_child(p_scene);
|
||||
animation_editor->set_root(p_scene);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EditorNode::_fetch_translatable_strings(const Object *p_object,Set<StringName>& strings) {
|
||||
|
||||
|
||||
@ -2818,6 +2892,115 @@ Error EditorNode::save_optimized_copy(const String& p_scene,const String& p_pres
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
Dictionary EditorNode::_get_main_scene_state() {
|
||||
|
||||
Dictionary state;
|
||||
state["main_tab"]=main_editor_tabs->get_current_tab();
|
||||
state["scene_tree_offset"]=scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->get_val();
|
||||
state["property_edit_offset"]=get_property_editor()->get_scene_tree()->get_vscroll_bar()->get_val();
|
||||
state["saved_version"]=saved_version;
|
||||
//print_line(" getting main tab: "+itos(state["main_tab"]));
|
||||
return state;
|
||||
}
|
||||
|
||||
void EditorNode::_set_main_scene_state(Dictionary p_state) {
|
||||
|
||||
//print_line("set current 7 ");
|
||||
|
||||
if (p_state.has("main_tab")) {
|
||||
int idx = p_state["main_tab"];
|
||||
int current=-1;
|
||||
for(int i=0;i<editor_table.size();i++) {
|
||||
if (editor_plugin_screen==editor_table[i]) {
|
||||
current=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (idx<2 && current<2) {
|
||||
//only set tab for 2D and 3D
|
||||
_editor_select(p_state["main_tab"]);
|
||||
//print_line(" setting main tab: "+itos(p_state["main_tab"]));
|
||||
}
|
||||
}
|
||||
|
||||
if (p_state.has("scene_tree_offset"))
|
||||
scene_tree_dock->get_tree_editor()->get_scene_tree()->get_vscroll_bar()->set_val(p_state["scene_tree_offset"]);
|
||||
if (p_state.has("property_edit_offset"))
|
||||
get_property_editor()->get_scene_tree()->get_vscroll_bar()->set_val(p_state["property_edit_offset"]);
|
||||
|
||||
//print_line("set current 8 ");
|
||||
|
||||
|
||||
}
|
||||
|
||||
void EditorNode::set_current_version(uint64_t p_version) {
|
||||
|
||||
saved_version=p_version;
|
||||
editor_data.set_edited_scene_version(p_version);
|
||||
}
|
||||
|
||||
bool EditorNode::is_changing_scene() const {
|
||||
return changing_scene;
|
||||
}
|
||||
void EditorNode::set_current_scene(int p_idx) {
|
||||
|
||||
changing_scene=true;
|
||||
editor_data.save_edited_scene_state(editor_selection,&editor_history,_get_main_scene_state());
|
||||
|
||||
if (get_editor_data().get_edited_scene_root()) {
|
||||
if (get_editor_data().get_edited_scene_root()->get_parent()==scene_root)
|
||||
scene_root->remove_child(get_editor_data().get_edited_scene_root());
|
||||
animation_editor->set_root(NULL);
|
||||
}
|
||||
|
||||
//print_line("set current 2 ");
|
||||
|
||||
editor_selection->clear();
|
||||
editor_data.set_edited_scene(p_idx);
|
||||
|
||||
Node* new_scene = editor_data.get_edited_scene_root();
|
||||
|
||||
if (new_scene && new_scene->cast_to<Popup>())
|
||||
new_scene->cast_to<Popup>()->show(); //show popups
|
||||
|
||||
//print_line("set current 3 ");
|
||||
|
||||
scene_tree_dock->set_edited_scene(new_scene);
|
||||
if (get_tree())
|
||||
get_tree()->set_edited_scene_root(new_scene);
|
||||
|
||||
if (new_scene) {
|
||||
if (new_scene->get_parent()!=scene_root)
|
||||
scene_root->add_child(new_scene);
|
||||
animation_editor->set_root(new_scene);
|
||||
}
|
||||
//print_line("set current 4 ");
|
||||
|
||||
|
||||
Dictionary state = editor_data.restore_edited_scene_state(editor_selection,&editor_history);
|
||||
_edit_current();
|
||||
|
||||
/*if (!unsaved) {
|
||||
saved_version=editor_data.get_undo_redo().get_version();
|
||||
if (p_backwards)
|
||||
saved_version--;
|
||||
else
|
||||
saved_version++;
|
||||
print_line("was saved, updating version");
|
||||
} else {
|
||||
saved_version=state["saved_version"];
|
||||
}*/
|
||||
//_set_main_scene_state(state);
|
||||
|
||||
call_deferred("_set_main_scene_state",state); //do after everything else is done setting up
|
||||
//print_line("set current 6 ");
|
||||
changing_scene=false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
Error EditorNode::load_scene(const String& p_scene) {
|
||||
|
||||
if (!is_inside_tree()) {
|
||||
@ -2826,6 +3009,14 @@ Error EditorNode::load_scene(const String& p_scene) {
|
||||
}
|
||||
|
||||
|
||||
for(int i=0;i<editor_data.get_edited_scene_count();i++) {
|
||||
|
||||
if (editor_data.get_scene_path(i)==p_scene) {
|
||||
_scene_tab_changed(i);
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
load_errors->clear();
|
||||
String lpath = Globals::get_singleton()->localize_path(p_scene);
|
||||
@ -2841,9 +3032,22 @@ Error EditorNode::load_scene(const String& p_scene) {
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded.
|
||||
int prev = editor_data.get_edited_scene();
|
||||
int idx = editor_data.add_edited_scene(-1);
|
||||
//print_line("load scene callback");
|
||||
//set_current_scene(idx);
|
||||
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(lpath);
|
||||
if (!editor_data.get_edited_scene_root() && editor_data.get_edited_scene_count()==2) {
|
||||
_remove_edited_scene();
|
||||
} else {
|
||||
_scene_tab_changed(idx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//_cleanup_scene(); // i'm sorry but this MUST happen to avoid modified resources to not be reloaded.
|
||||
|
||||
Ref<PackedScene> sdata = ResourceLoader::load(lpath,"",true);
|
||||
if (!sdata.is_valid()) {
|
||||
|
||||
current_option=-1;
|
||||
@ -2852,22 +3056,37 @@ Error EditorNode::load_scene(const String& p_scene) {
|
||||
accept->set_text("Error loading scene.");
|
||||
accept->popup_centered_minsize();
|
||||
opening_prev=false;
|
||||
|
||||
if (prev!=-1) {
|
||||
set_current_scene(prev);
|
||||
editor_data.remove_scene(idx);
|
||||
}
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
sdata->set_path(lpath,true); //take over path
|
||||
|
||||
Node*new_scene=sdata->instance(true);
|
||||
|
||||
if (!new_scene) {
|
||||
|
||||
sdata.unref();
|
||||
current_option=-1;
|
||||
//accept->get_cancel()->hide();
|
||||
accept->get_ok()->set_text("Ugh");
|
||||
accept->set_text("Error loading scene.");
|
||||
accept->popup_centered_minsize();
|
||||
opening_prev=false;
|
||||
if (prev!=-1) {
|
||||
set_current_scene(prev);
|
||||
editor_data.remove_scene(idx);
|
||||
}
|
||||
return ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
//guess not needed in the end?
|
||||
//new_scene->clear_internal_tree_resource_paths(); //make sure no internal tree paths to internal resources exist
|
||||
|
||||
/*
|
||||
Node *old_scene = edited_scene;
|
||||
_hide_top_editors();
|
||||
@ -2880,16 +3099,23 @@ Error EditorNode::load_scene(const String& p_scene) {
|
||||
memdelete(old_scene);
|
||||
}
|
||||
*/
|
||||
|
||||
set_edited_scene(new_scene);
|
||||
_get_scene_metadata();
|
||||
/*
|
||||
editor_data.set_edited_scene_root(new_scene);
|
||||
|
||||
scene_tree_dock->set_selected(new_scene, true);
|
||||
property_editor->edit(new_scene);
|
||||
scene_import_metadata = sdata->get_import_metadata();
|
||||
editor_data.set_edited_scene_root(new_scene);
|
||||
*/
|
||||
editor_data.set_edited_scene_import_metadata( sdata->get_import_metadata() );
|
||||
|
||||
editor_data.get_undo_redo().clear_history();
|
||||
|
||||
// editor_data.get_undo_redo().clear_history();
|
||||
saved_version=editor_data.get_undo_redo().get_version();
|
||||
_update_title();
|
||||
|
||||
_update_scene_tabs();
|
||||
_add_to_recent_scenes(lpath);
|
||||
|
||||
if (new_scene->has_meta("__editor_plugin_screen__")) {
|
||||
@ -2919,8 +3145,9 @@ Error EditorNode::load_scene(const String& p_scene) {
|
||||
|
||||
void EditorNode::open_request(const String& p_path) {
|
||||
|
||||
external_file=p_path;
|
||||
_menu_option_confirm(FILE_EXTERNAL_OPEN_SCENE,false);
|
||||
load_scene(p_path); // as it will be opened in separate tab
|
||||
//external_file=p_path;
|
||||
//_menu_option_confirm(FILE_EXTERNAL_OPEN_SCENE,false);
|
||||
}
|
||||
|
||||
|
||||
@ -3058,15 +3285,16 @@ void EditorNode::_open_recent_scene(int p_idx) {
|
||||
|
||||
String path = "res://"+rc[p_idx];
|
||||
|
||||
if (unsaved_cache) {
|
||||
|
||||
/*if (unsaved_cache) {
|
||||
_recent_scene=rc[p_idx];
|
||||
open_recent_confirmation->set_text("Discard current scene and open:\n'"+rc[p_idx]+"'");
|
||||
open_recent_confirmation->get_label()->set_align(Label::ALIGN_CENTER);
|
||||
open_recent_confirmation->popup_centered(Size2(400,100));
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
|
||||
load_scene(rc[p_idx]);
|
||||
load_scene(path);
|
||||
|
||||
|
||||
}
|
||||
@ -3110,12 +3338,6 @@ void EditorNode::_save_optimized() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void EditorNode::_open_recent_scene_confirm() {
|
||||
|
||||
load_scene(_recent_scene);
|
||||
|
||||
}
|
||||
|
||||
void EditorNode::_update_recent_scenes() {
|
||||
|
||||
String base="_"+Globals::get_singleton()->get_resource_path().replace("\\","::").replace("/","::");
|
||||
@ -3236,6 +3458,7 @@ void EditorNode::register_editor_types() {
|
||||
ObjectTypeDB::register_type<EditorScenePostImport>();
|
||||
ObjectTypeDB::register_type<EditorScript>();
|
||||
ObjectTypeDB::register_type<EditorFileDialog>();
|
||||
ObjectTypeDB::register_type<UndoRedo>();
|
||||
|
||||
|
||||
//ObjectTypeDB::register_type<EditorImporter>();
|
||||
@ -3325,7 +3548,7 @@ void EditorNode::_bind_methods() {
|
||||
//ObjectTypeDB::bind_method("_import",&EditorNode::_import);
|
||||
// ObjectTypeDB::bind_method("_import_conflicts_solved",&EditorNode::_import_conflicts_solved);
|
||||
ObjectTypeDB::bind_method("_open_recent_scene",&EditorNode::_open_recent_scene);
|
||||
ObjectTypeDB::bind_method("_open_recent_scene_confirm",&EditorNode::_open_recent_scene_confirm);
|
||||
// ObjectTypeDB::bind_method("_open_recent_scene_confirm",&EditorNode::_open_recent_scene_confirm);
|
||||
|
||||
ObjectTypeDB::bind_method("_save_optimized",&EditorNode::_save_optimized);
|
||||
ObjectTypeDB::bind_method(_MD("animation_panel_make_visible","enable"),&EditorNode::animation_panel_make_visible);
|
||||
@ -3343,6 +3566,11 @@ 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("set_current_scene",&EditorNode::set_current_scene);
|
||||
ObjectTypeDB::bind_method("set_current_version",&EditorNode::set_current_version);
|
||||
ObjectTypeDB::bind_method("_scene_tab_changed",&EditorNode::_scene_tab_changed);
|
||||
ObjectTypeDB::bind_method("_set_main_scene_state",&EditorNode::_set_main_scene_state);
|
||||
ObjectTypeDB::bind_method("_update_scene_tabs",&EditorNode::_update_scene_tabs);
|
||||
|
||||
|
||||
|
||||
@ -3655,10 +3883,29 @@ void EditorNode::_save_docks() {
|
||||
}
|
||||
|
||||
|
||||
HSplitContainer *h_splits[4]={
|
||||
left_l_hsplit,
|
||||
left_r_hsplit,
|
||||
main_hsplit,
|
||||
right_hsplit,
|
||||
};
|
||||
|
||||
for(int i=0;i<4;i++) {
|
||||
|
||||
config->set_value("docks","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() {
|
||||
|
||||
dock_drag_timer->start();
|
||||
}
|
||||
|
||||
void EditorNode::_dock_split_dragged(int ofs) {
|
||||
|
||||
dock_drag_timer->start();
|
||||
@ -3732,6 +3979,20 @@ void EditorNode::_load_docks() {
|
||||
splits[i]->set_split_offset(ofs);
|
||||
}
|
||||
|
||||
HSplitContainer *h_splits[4]={
|
||||
left_l_hsplit,
|
||||
left_r_hsplit,
|
||||
main_hsplit,
|
||||
right_hsplit,
|
||||
};
|
||||
|
||||
for(int i=0;i<4;i++) {
|
||||
if (!config->has_section_key("docks","dock_hsplit_"+itos(i+1)))
|
||||
continue;
|
||||
int ofs = config->get_value("docks","dock_hsplit_"+itos(i+1));
|
||||
h_splits[i]->set_split_offset(ofs);
|
||||
}
|
||||
|
||||
for(int i=0;i<DOCK_SLOT_MAX/2;i++) {
|
||||
bool in_use = dock_slot[i*2+0]->get_tab_count() || dock_slot[i*2+1]->get_tab_count();
|
||||
if (in_use)
|
||||
@ -3747,6 +4008,38 @@ void EditorNode::_load_docks() {
|
||||
}
|
||||
}
|
||||
|
||||
editor_data.set_plugin_window_layout(config);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EditorNode::_scene_tab_changed(int p_tab) {
|
||||
|
||||
|
||||
//print_line("set current 1 ");
|
||||
bool unsaved = (saved_version!=editor_data.get_undo_redo().get_version());
|
||||
//print_line("version: "+itos(editor_data.get_undo_redo().get_version())+", saved "+itos(saved_version));
|
||||
|
||||
if (p_tab==editor_data.get_edited_scene())
|
||||
return; //pointless
|
||||
|
||||
uint64_t next_scene_version = editor_data.get_scene_version(p_tab);
|
||||
|
||||
|
||||
|
||||
//print_line("scene tab changed???");
|
||||
editor_data.get_undo_redo().create_action("Switch Scene Tab");
|
||||
editor_data.get_undo_redo().add_do_method(this,"set_current_version",unsaved?saved_version:0);
|
||||
editor_data.get_undo_redo().add_do_method(this,"set_current_scene",p_tab);
|
||||
editor_data.get_undo_redo().add_do_method(scene_tabs,"set_current_tab",p_tab);
|
||||
editor_data.get_undo_redo().add_do_method(this,"set_current_version",next_scene_version==0?editor_data.get_undo_redo().get_version()+1:next_scene_version);
|
||||
|
||||
editor_data.get_undo_redo().add_undo_method(this,"set_current_version",next_scene_version);
|
||||
editor_data.get_undo_redo().add_undo_method(this,"set_current_scene",editor_data.get_edited_scene());
|
||||
editor_data.get_undo_redo().add_undo_method(scene_tabs,"set_current_tab",editor_data.get_edited_scene());
|
||||
editor_data.get_undo_redo().add_undo_method(this,"set_current_version",saved_version);
|
||||
editor_data.get_undo_redo().commit_action();
|
||||
|
||||
}
|
||||
|
||||
EditorNode::EditorNode() {
|
||||
@ -3754,6 +4047,8 @@ EditorNode::EditorNode() {
|
||||
EditorHelp::generate_doc(); //before any editor classes are crated
|
||||
|
||||
singleton=this;
|
||||
last_checked_version=0;
|
||||
changing_scene=false;
|
||||
|
||||
FileAccess::set_backup_save(true);
|
||||
|
||||
@ -3841,14 +4136,38 @@ EditorNode::EditorNode() {
|
||||
gui_base->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
|
||||
gui_base->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END );
|
||||
gui_base->set_end( Point2(0,0) );
|
||||
|
||||
|
||||
main_vbox = memnew( VBoxContainer );
|
||||
gui_base->add_child(main_vbox);
|
||||
main_vbox->set_area_as_parent_rect(8);
|
||||
|
||||
menu_hb = memnew( HBoxContainer );
|
||||
main_vbox->add_child(menu_hb);
|
||||
PanelContainer *top_dark_panel = memnew( PanelContainer );
|
||||
Ref<StyleBoxTexture> top_dark_sb;
|
||||
top_dark_sb.instance();;
|
||||
top_dark_sb->set_texture(theme->get_icon("PanelTop","EditorIcons"));
|
||||
for(int i=0;i<4;i++) {
|
||||
top_dark_sb->set_margin_size(Margin(i),3);
|
||||
top_dark_sb->set_default_margin(Margin(i),0);
|
||||
}
|
||||
top_dark_sb->set_expand_margin_size(MARGIN_LEFT,20);
|
||||
top_dark_sb->set_expand_margin_size(MARGIN_RIGHT,20);
|
||||
|
||||
top_dark_panel->add_style_override("panel",top_dark_sb);
|
||||
VBoxContainer *top_dark_vb = memnew( VBoxContainer );
|
||||
main_vbox->add_child(top_dark_panel);
|
||||
top_dark_panel->add_child(top_dark_vb);
|
||||
|
||||
|
||||
|
||||
|
||||
menu_hb = memnew( HBoxContainer );
|
||||
top_dark_vb->add_child(menu_hb);
|
||||
|
||||
scene_tabs=memnew( Tabs );
|
||||
scene_tabs->add_tab("unsaved");
|
||||
scene_tabs->set_tab_align(Tabs::ALIGN_CENTER);
|
||||
scene_tabs->connect("tab_changed",this,"_scene_tab_changed");
|
||||
top_dark_vb->add_child(scene_tabs);
|
||||
//left
|
||||
left_l_hsplit = memnew( HSplitContainer );
|
||||
main_vbox->add_child(left_l_hsplit);
|
||||
@ -3912,6 +4231,12 @@ EditorNode::EditorNode() {
|
||||
right_l_vsplit->connect("dragged",this,"_dock_split_dragged");
|
||||
right_r_vsplit->connect("dragged",this,"_dock_split_dragged");
|
||||
|
||||
left_l_hsplit->connect("dragged",this,"_dock_split_dragged");
|
||||
left_r_hsplit->connect("dragged",this,"_dock_split_dragged");
|
||||
main_hsplit->connect("dragged",this,"_dock_split_dragged");
|
||||
right_hsplit->connect("dragged",this,"_dock_split_dragged");
|
||||
|
||||
|
||||
|
||||
dock_select_popoup = memnew( PopupPanel );
|
||||
gui_base->add_child(dock_select_popoup);
|
||||
@ -3951,7 +4276,7 @@ EditorNode::EditorNode() {
|
||||
//dock_select_popoup->set_(Size2(20,20));
|
||||
|
||||
for(int i=0;i<DOCK_SLOT_MAX;i++) {
|
||||
dock_slot[i]->set_custom_minimum_size(Size2(250,250));
|
||||
dock_slot[i]->set_custom_minimum_size(Size2(230,220));
|
||||
dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
dock_slot[i]->set_popup(dock_select_popoup);
|
||||
dock_slot[i]->connect("pre_popup_pressed",this,"_dock_pre_popup",varray(i));
|
||||
@ -4101,7 +4426,9 @@ EditorNode::EditorNode() {
|
||||
p->add_item("Save Scene",FILE_SAVE_SCENE,KEY_MASK_CMD+KEY_S);
|
||||
p->add_item("Save Scene As..",FILE_SAVE_AS_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_S);
|
||||
p->add_separator();
|
||||
p->add_item("Goto Prev. Scene",FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P);
|
||||
p->add_item("Close Scene",FILE_CLOSE,KEY_MASK_SHIFT+KEY_MASK_CTRL+KEY_W);
|
||||
p->add_separator();
|
||||
p->add_item("Close Goto Prev. Scene",FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P);
|
||||
p->add_submenu_item("Open Recent","RecentScenes",FILE_OPEN_RECENT);
|
||||
p->add_separator();
|
||||
p->add_item("Quick Open Scene..",FILE_QUICK_OPEN_SCENE,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_O);
|
||||
@ -4727,6 +5054,7 @@ EditorNode::EditorNode() {
|
||||
add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( ColorRampEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( CollisionShape2DEditorPlugin(this) ) );
|
||||
|
||||
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
|
||||
add_editor_plugin( EditorPlugins::create(i,this) );
|
||||
@ -4791,8 +5119,8 @@ EditorNode::EditorNode() {
|
||||
}
|
||||
|
||||
|
||||
edited_scene=NULL;
|
||||
saved_version=0;
|
||||
//edited_scene=NULL;
|
||||
saved_version=1;
|
||||
unsaved_cache=true;
|
||||
_last_instanced_scene=NULL;
|
||||
|
||||
@ -4854,7 +5182,13 @@ EditorNode::EditorNode() {
|
||||
for(int i=0;i<_init_callbacks.size();i++)
|
||||
_init_callbacks[i]();
|
||||
|
||||
editor_data.add_edited_scene(-1);
|
||||
editor_data.set_edited_scene(0);
|
||||
_update_scene_tabs();
|
||||
|
||||
_load_docks();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -125,6 +125,7 @@ class EditorNode : public Node {
|
||||
FILE_QUICK_OPEN_SCRIPT,
|
||||
FILE_RUN_SCRIPT,
|
||||
FILE_OPEN_PREV,
|
||||
FILE_CLOSE,
|
||||
FILE_QUIT,
|
||||
FILE_EXTERNAL_OPEN_SCENE,
|
||||
EDIT_UNDO,
|
||||
@ -183,16 +184,16 @@ class EditorNode : public Node {
|
||||
};
|
||||
|
||||
|
||||
Node *edited_scene; //scene being edited
|
||||
//Node *edited_scene; //scene being edited
|
||||
Viewport *scene_root; //root of the scene being edited
|
||||
|
||||
Ref<ResourceImportMetadata> scene_import_metadata;
|
||||
//Ref<ResourceImportMetadata> scene_import_metadata;
|
||||
|
||||
Control* scene_root_parent;
|
||||
Control *gui_base;
|
||||
VBoxContainer *main_vbox;
|
||||
|
||||
|
||||
//split
|
||||
|
||||
HSplitContainer *left_l_hsplit;
|
||||
VSplitContainer *left_l_vsplit;
|
||||
@ -205,6 +206,9 @@ class EditorNode : public Node {
|
||||
|
||||
VSplitContainer *center_split;
|
||||
|
||||
//main tabs
|
||||
|
||||
Tabs *scene_tabs;
|
||||
|
||||
|
||||
int old_split_ofs;
|
||||
@ -324,8 +328,10 @@ class EditorNode : public Node {
|
||||
bool reference_resource_mem;
|
||||
bool save_external_resources_mem;
|
||||
uint64_t saved_version;
|
||||
uint64_t last_checked_version;
|
||||
bool unsaved_cache;
|
||||
String open_navigate;
|
||||
bool changing_scene;
|
||||
|
||||
uint32_t circle_step_msec;
|
||||
uint64_t circle_step_frame;
|
||||
@ -375,6 +381,7 @@ class EditorNode : public Node {
|
||||
void _set_scene_metadata();
|
||||
void _get_scene_metadata();
|
||||
void _update_title();
|
||||
void _update_scene_tabs();
|
||||
void _close_messages();
|
||||
void _show_messages();
|
||||
void _vp_resized();
|
||||
@ -402,7 +409,7 @@ class EditorNode : public Node {
|
||||
void _add_to_recent_scenes(const String& p_scene);
|
||||
void _update_recent_scenes();
|
||||
void _open_recent_scene(int p_idx);
|
||||
void _open_recent_scene_confirm();
|
||||
//void _open_recent_scene_confirm();
|
||||
String _recent_scene;
|
||||
|
||||
bool convert_old;
|
||||
@ -431,7 +438,7 @@ class EditorNode : public Node {
|
||||
|
||||
|
||||
void _cleanup_scene();
|
||||
|
||||
void _remove_edited_scene();
|
||||
bool _find_and_save_resource(RES p_res,Map<RES,bool>& processed,int32_t flags);
|
||||
bool _find_and_save_edited_subresources(Object *obj,Map<RES,bool>& processed,int32_t flags);
|
||||
void _save_edited_subresources(Node* scene,Map<RES,bool>& processed,int32_t flags);
|
||||
@ -461,6 +468,10 @@ class EditorNode : public Node {
|
||||
void _dock_pre_popup(int p_which);
|
||||
void _dock_split_dragged(int ofs);
|
||||
void _dock_popup_exit();
|
||||
void _scene_tab_changed(int p_tab);
|
||||
|
||||
Dictionary _get_main_scene_state();
|
||||
void _set_main_scene_state(Dictionary p_state);
|
||||
|
||||
void _save_docks();
|
||||
void _load_docks();
|
||||
@ -498,7 +509,7 @@ public:
|
||||
|
||||
void open_request(const String& p_path);
|
||||
|
||||
void set_edited_scene(Node *p_scene);
|
||||
bool is_changing_scene() const;
|
||||
|
||||
|
||||
static EditorLog *get_log() { return singleton->log; }
|
||||
@ -511,7 +522,9 @@ public:
|
||||
void hide_animation_player_editors();
|
||||
void animation_panel_make_visible(bool p_visible);
|
||||
|
||||
Node *get_edited_scene() { return edited_scene; }
|
||||
void set_edited_scene(Node *p_scene);
|
||||
|
||||
Node *get_edited_scene() { return editor_data.get_edited_scene_root(); }
|
||||
|
||||
Viewport *get_scene_root() { return scene_root; } //root of the scene being edited
|
||||
Error save_optimized_copy(const String& p_scene,const String& p_preset);
|
||||
@ -520,6 +533,9 @@ public:
|
||||
Error load_scene(const String& p_scene);
|
||||
Error load_resource(const String& p_scene);
|
||||
|
||||
void set_current_version(uint64_t p_version);
|
||||
void set_current_scene(int p_idx);
|
||||
|
||||
static EditorData& get_editor_data() { return singleton->editor_data; }
|
||||
|
||||
static VSplitContainer *get_top_split() { return singleton->top_split; }
|
||||
@ -566,6 +582,9 @@ public:
|
||||
bool is_scene_in_use(const String& p_path);
|
||||
|
||||
void scan_import_changes();
|
||||
|
||||
void save_layout();
|
||||
|
||||
EditorNode();
|
||||
~EditorNode();
|
||||
void get_singleton(const char* arg1, bool arg2);
|
||||
|
@ -197,6 +197,13 @@ bool EditorPlugin::get_remove_list(List<Node*> *p_list) {
|
||||
void EditorPlugin::restore_global_state() {}
|
||||
void EditorPlugin::save_global_state() {}
|
||||
|
||||
void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
|
||||
|
||||
}
|
||||
|
||||
void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){
|
||||
|
||||
}
|
||||
|
||||
void EditorPlugin::_bind_methods() {
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "scene/main/node.h"
|
||||
#include "scene/resources/texture.h"
|
||||
#include "undo_redo.h"
|
||||
|
||||
#include "io/config_file.h"
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
@ -90,6 +90,8 @@ public:
|
||||
virtual void apply_changes() ; // if changes are pending in editor, apply them
|
||||
virtual void get_breakpoints(List<String> *p_breakpoints);
|
||||
virtual bool get_remove_list(List<Node*> *p_list);
|
||||
virtual void set_window_layout(Ref<ConfigFile> p_layout);
|
||||
virtual void get_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
||||
virtual void restore_global_state();
|
||||
virtual void save_global_state();
|
||||
|
@ -18,7 +18,7 @@ void EditorScript::add_root_node(Node *p_node) {
|
||||
return;
|
||||
}
|
||||
|
||||
editor->set_edited_scene(p_node);
|
||||
// editor->set_edited_scene(p_node);
|
||||
}
|
||||
|
||||
Node *EditorScript::get_scene() {
|
||||
|
@ -433,9 +433,11 @@ void EditorSettings::_load_defaults() {
|
||||
set("text_editor/idle_parse_delay",2);
|
||||
set("text_editor/create_signal_callbacks",true);
|
||||
set("text_editor/autosave_interval_secs",0);
|
||||
|
||||
set("text_editor/font","");
|
||||
hints["text_editor/font"]=PropertyInfo(Variant::STRING,"text_editor/font",PROPERTY_HINT_GLOBAL_FILE,"*.fnt");
|
||||
set("text_editor/auto_brace_complete", false);
|
||||
set("text_editor/restore_scripts_on_load",true);
|
||||
|
||||
|
||||
set("scenetree_editor/duplicate_node_name_num_separator",0);
|
||||
|
BIN
tools/editor/icons/icon_panel_top.png
Normal file
BIN
tools/editor/icons/icon_panel_top.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 195 B |
BIN
tools/editor/icons/icon_script_list.png
Normal file
BIN
tools/editor/icons/icon_script_list.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 213 B |
@ -105,7 +105,7 @@ public:
|
||||
_EditorMeshImportOptions() {
|
||||
|
||||
generate_tangents=true;
|
||||
generate_normals=true;
|
||||
generate_normals=false;
|
||||
flip_faces=false;
|
||||
smooth_shading=false;
|
||||
weld_vertices=true;
|
||||
|
533
tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
Normal file
533
tools/editor/plugins/collision_shape_2d_editor_plugin.cpp
Normal file
@ -0,0 +1,533 @@
|
||||
#include "collision_shape_2d_editor_plugin.h"
|
||||
|
||||
#include "canvas_item_editor_plugin.h"
|
||||
|
||||
#include "scene/resources/segment_shape_2d.h"
|
||||
#include "scene/resources/shape_line_2d.h"
|
||||
#include "scene/resources/circle_shape_2d.h"
|
||||
#include "scene/resources/rectangle_shape_2d.h"
|
||||
#include "scene/resources/capsule_shape_2d.h"
|
||||
#include "scene/resources/convex_polygon_shape_2d.h"
|
||||
#include "scene/resources/concave_polygon_shape_2d.h"
|
||||
|
||||
Variant CollisionShape2DEditor::get_handle_value(int idx) const {
|
||||
|
||||
switch ( shape_type ) {
|
||||
case CAPSULE_SHAPE: {
|
||||
Ref<CapsuleShape2D> capsule = node->get_shape();
|
||||
|
||||
if (idx==0) {
|
||||
return capsule->get_radius();
|
||||
} else if (idx==1) {
|
||||
return capsule->get_height();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case CIRCLE_SHAPE: {
|
||||
Ref<CircleShape2D> circle = node->get_shape();
|
||||
|
||||
if (idx==0) {
|
||||
return circle->get_radius();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case CONCAVE_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case CONVEX_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case LINE_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> ray = node->get_shape();
|
||||
|
||||
if (idx==0) {
|
||||
return ray->get_length();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case RECTANGLE_SHAPE: {
|
||||
Ref<RectangleShape2D> rect = node->get_shape();
|
||||
|
||||
if (idx<2) {
|
||||
return rect->get_extents().abs();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case SEGMENT_SHAPE: {
|
||||
Ref<SegmentShape2D> seg = node->get_shape();
|
||||
|
||||
if (idx==0) {
|
||||
return seg->get_a();
|
||||
} else if (idx==1) {
|
||||
return seg->get_b();
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
return Variant();
|
||||
}
|
||||
|
||||
void CollisionShape2DEditor::set_handle(int idx, Point2& p_point) {
|
||||
|
||||
switch ( shape_type ) {
|
||||
case CAPSULE_SHAPE: {
|
||||
if (idx < 2) {
|
||||
Ref<CapsuleShape2D> capsule = node->get_shape();
|
||||
|
||||
real_t parameter = Math::abs(p_point[idx]);
|
||||
|
||||
if (idx==0) {
|
||||
capsule->set_radius(parameter);
|
||||
} else if (idx==1){
|
||||
capsule->set_height(parameter*2 - capsule->get_radius()*2);
|
||||
}
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case CIRCLE_SHAPE: {
|
||||
Ref<CircleShape2D> circle = node->get_shape();
|
||||
circle->set_radius(p_point.length());
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
|
||||
} break;
|
||||
|
||||
case CONCAVE_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case CONVEX_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case LINE_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> ray = node->get_shape();
|
||||
|
||||
ray->set_length(Math::abs(p_point.y));
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
|
||||
} break;
|
||||
|
||||
case RECTANGLE_SHAPE: {
|
||||
if (idx<2) {
|
||||
Ref<RectangleShape2D> rect = node->get_shape();
|
||||
|
||||
Vector2 extents = rect->get_extents();
|
||||
extents[idx] = p_point[idx];
|
||||
|
||||
rect->set_extents(extents.abs());
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case SEGMENT_SHAPE: {
|
||||
if (edit_handle < 2) {
|
||||
Ref<SegmentShape2D> seg = node->get_shape();
|
||||
|
||||
if (idx==0) {
|
||||
seg->set_a(p_point);
|
||||
} else if (idx==1) {
|
||||
seg->set_b(p_point);
|
||||
}
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionShape2DEditor::commit_handle(int idx, Variant& p_org) {
|
||||
|
||||
Control* c = canvas_item_editor->get_viewport_control();
|
||||
undo_redo->create_action("Set Handle");
|
||||
|
||||
switch ( shape_type ) {
|
||||
case CAPSULE_SHAPE: {
|
||||
Ref<CapsuleShape2D> capsule = node->get_shape();
|
||||
|
||||
if (idx==0) {
|
||||
undo_redo->add_do_method(capsule.ptr(),"set_radius",capsule->get_radius());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(capsule.ptr(),"set_radius",p_org);
|
||||
undo_redo->add_do_method(c,"update");
|
||||
} else if (idx==1) {
|
||||
undo_redo->add_do_method(capsule.ptr(),"set_height",capsule->get_height());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(capsule.ptr(),"set_height",p_org);
|
||||
undo_redo->add_undo_method(c,"update");
|
||||
}
|
||||
|
||||
} break;
|
||||
|
||||
case CIRCLE_SHAPE: {
|
||||
Ref<CircleShape2D> circle = node->get_shape();
|
||||
|
||||
undo_redo->add_do_method(circle.ptr(),"set_radius",circle->get_radius());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(circle.ptr(),"set_radius",p_org);
|
||||
undo_redo->add_undo_method(c,"update");
|
||||
|
||||
} break;
|
||||
|
||||
case CONCAVE_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case CONVEX_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case LINE_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> ray = node->get_shape();
|
||||
|
||||
undo_redo->add_do_method(ray.ptr(),"set_length",ray->get_length());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(ray.ptr(),"set_length",p_org);
|
||||
undo_redo->add_undo_method(c,"update");
|
||||
|
||||
} break;
|
||||
|
||||
case RECTANGLE_SHAPE: {
|
||||
Ref<RectangleShape2D> rect = node->get_shape();
|
||||
|
||||
undo_redo->add_do_method(rect.ptr(),"set_extents",rect->get_extents());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(rect.ptr(),"set_extents",p_org);
|
||||
undo_redo->add_undo_method(c,"update");
|
||||
|
||||
} break;
|
||||
|
||||
case SEGMENT_SHAPE: {
|
||||
Ref<SegmentShape2D> seg = node->get_shape();
|
||||
if (idx==0) {
|
||||
undo_redo->add_do_method(seg.ptr(),"set_a",seg->get_a());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(seg.ptr(),"set_a",p_org);
|
||||
undo_redo->add_undo_method(c,"update");
|
||||
} else if (idx==1) {
|
||||
undo_redo->add_do_method(seg.ptr(),"set_b",seg->get_b());
|
||||
undo_redo->add_do_method(c,"update");
|
||||
undo_redo->add_undo_method(seg.ptr(),"set_b",p_org);
|
||||
undo_redo->add_undo_method(c,"update");
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
bool CollisionShape2DEditor::forward_input_event(const InputEvent& p_event) {
|
||||
|
||||
if (!node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!node->get_shape().is_valid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (shape_type == -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch( p_event.type ) {
|
||||
case InputEvent::MOUSE_BUTTON: {
|
||||
const InputEventMouseButton& mb = p_event.mouse_button;
|
||||
|
||||
Matrix32 gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
|
||||
|
||||
Point2 gpoint(mb.x,mb.y);
|
||||
|
||||
if (mb.button_index == BUTTON_LEFT) {
|
||||
if (mb.pressed) {
|
||||
for (int i = 0; i < handles.size(); i++) {
|
||||
if (gt.xform(handles[i]).distance_to(gpoint) < 8) {
|
||||
edit_handle = i;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (edit_handle==-1) {
|
||||
pressed = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
original = get_handle_value(edit_handle);
|
||||
pressed = true;
|
||||
|
||||
return true;
|
||||
|
||||
} else {
|
||||
if (pressed) {
|
||||
commit_handle(edit_handle, original);
|
||||
|
||||
edit_handle = -1;
|
||||
pressed = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
} break;
|
||||
|
||||
case InputEvent::MOUSE_MOTION: {
|
||||
const InputEventMouseMotion& mm = p_event.mouse_motion;
|
||||
|
||||
if (edit_handle == -1 || !pressed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Point2 gpoint = Point2(mm.x,mm.y);
|
||||
Point2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
|
||||
cpoint = canvas_item_editor->snap_point(cpoint);
|
||||
cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
|
||||
|
||||
set_handle(edit_handle, cpoint);
|
||||
|
||||
return true;
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CollisionShape2DEditor::_get_current_shape_type() {
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
Ref<Shape2D> s = node->get_shape();
|
||||
|
||||
if (!s.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (s->cast_to<CapsuleShape2D>()) {
|
||||
shape_type = CAPSULE_SHAPE;
|
||||
} else if (s->cast_to<CircleShape2D>()) {
|
||||
shape_type = CIRCLE_SHAPE;
|
||||
} else if (s->cast_to<ConcavePolygonShape2D>()) {
|
||||
shape_type = CONCAVE_POLYGON_SHAPE;
|
||||
} else if (s->cast_to<ConvexPolygonShape2D>()) {
|
||||
shape_type = CONVEX_POLYGON_SHAPE;
|
||||
} else if (s->cast_to<LineShape2D>()) {
|
||||
shape_type = LINE_SHAPE;
|
||||
} else if (s->cast_to<RayShape2D>()) {
|
||||
shape_type = RAY_SHAPE;
|
||||
} else if (s->cast_to<RectangleShape2D>()) {
|
||||
shape_type = RECTANGLE_SHAPE;
|
||||
} else if (s->cast_to<SegmentShape2D>()) {
|
||||
shape_type = SEGMENT_SHAPE;
|
||||
} else {
|
||||
shape_type = -1;
|
||||
}
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
}
|
||||
|
||||
void CollisionShape2DEditor::_canvas_draw() {
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!node->get_shape().is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_get_current_shape_type();
|
||||
|
||||
if (shape_type == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Control *c = canvas_item_editor->get_viewport_control();
|
||||
Matrix32 gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
|
||||
|
||||
Ref<Texture> h = get_icon("EditorHandle","EditorIcons");
|
||||
Vector2 size = h->get_size()*0.5;
|
||||
|
||||
handles.clear();
|
||||
|
||||
switch (shape_type) {
|
||||
case CAPSULE_SHAPE: {
|
||||
Ref<CapsuleShape2D> shape = node->get_shape();
|
||||
|
||||
handles.resize(2);
|
||||
float radius = shape->get_radius();
|
||||
float height = shape->get_height()/2;
|
||||
|
||||
handles[0] = Point2(radius, -height);
|
||||
handles[1] = Point2(0,-(height + radius));
|
||||
|
||||
c->draw_texture(h, gt.xform(handles[0])-size);
|
||||
c->draw_texture(h, gt.xform(handles[1])-size);
|
||||
|
||||
} break;
|
||||
|
||||
case CIRCLE_SHAPE: {
|
||||
Ref<CircleShape2D> shape = node->get_shape();
|
||||
|
||||
handles.resize(1);
|
||||
handles[0] = Point2(shape->get_radius(),0);
|
||||
|
||||
c->draw_texture(h, gt.xform(handles[0])-size);
|
||||
|
||||
} break;
|
||||
|
||||
case CONCAVE_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case CONVEX_POLYGON_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case LINE_SHAPE: {
|
||||
|
||||
} break;
|
||||
|
||||
case RAY_SHAPE: {
|
||||
Ref<RayShape2D> shape = node->get_shape();
|
||||
|
||||
handles.resize(1);
|
||||
handles[0] = Point2(0,shape->get_length());
|
||||
|
||||
c->draw_texture(h,gt.xform(handles[0])-size);
|
||||
|
||||
} break;
|
||||
|
||||
case RECTANGLE_SHAPE: {
|
||||
Ref<RectangleShape2D> shape = node->get_shape();
|
||||
|
||||
handles.resize(2);
|
||||
Vector2 ext = shape->get_extents();
|
||||
handles[0] = Point2(ext.x,0);
|
||||
handles[1] = Point2(0,-ext.y);
|
||||
|
||||
c->draw_texture(h,gt.xform(handles[0])-size);
|
||||
c->draw_texture(h,gt.xform(handles[1])-size);
|
||||
|
||||
} break;
|
||||
|
||||
case SEGMENT_SHAPE: {
|
||||
Ref<SegmentShape2D> shape = node->get_shape();
|
||||
|
||||
handles.resize(2);
|
||||
handles[0] = shape->get_a();
|
||||
handles[1] = shape->get_b();
|
||||
|
||||
c->draw_texture(h, gt.xform(handles[0])-size);
|
||||
c->draw_texture(h, gt.xform(handles[1])-size);
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void CollisionShape2DEditor::edit(Node* p_node) {
|
||||
|
||||
if (!canvas_item_editor) {
|
||||
canvas_item_editor=CanvasItemEditor::get_singleton();
|
||||
}
|
||||
|
||||
if (p_node) {
|
||||
node=p_node->cast_to<CollisionShape2D>();
|
||||
|
||||
if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
|
||||
canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
|
||||
|
||||
_get_current_shape_type();
|
||||
|
||||
} else {
|
||||
edit_handle = -1;
|
||||
shape_type = -1;
|
||||
|
||||
if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
|
||||
canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw");
|
||||
|
||||
node=NULL;
|
||||
}
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
}
|
||||
|
||||
void CollisionShape2DEditor::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method("_canvas_draw",&CollisionShape2DEditor::_canvas_draw);
|
||||
ObjectTypeDB::bind_method("_get_current_shape_type",&CollisionShape2DEditor::_get_current_shape_type);
|
||||
}
|
||||
|
||||
CollisionShape2DEditor::CollisionShape2DEditor(EditorNode* p_editor) {
|
||||
|
||||
node = NULL;
|
||||
canvas_item_editor = NULL;
|
||||
editor = p_editor;
|
||||
|
||||
undo_redo = p_editor->get_undo_redo();
|
||||
|
||||
edit_handle = -1;
|
||||
pressed = false;
|
||||
}
|
||||
|
||||
void CollisionShape2DEditorPlugin::edit(Object* p_obj) {
|
||||
|
||||
collision_shape_2d_editor->edit(p_obj->cast_to<Node>());
|
||||
}
|
||||
|
||||
bool CollisionShape2DEditorPlugin::handles(Object* p_obj) const {
|
||||
|
||||
return p_obj->is_type("CollisionShape2D");
|
||||
}
|
||||
|
||||
void CollisionShape2DEditorPlugin::make_visible(bool visible) {
|
||||
|
||||
if (!visible) {
|
||||
edit(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
CollisionShape2DEditorPlugin::CollisionShape2DEditorPlugin(EditorNode* p_node) {
|
||||
|
||||
editor=p_node;
|
||||
|
||||
collision_shape_2d_editor = memnew( CollisionShape2DEditor(p_node) );
|
||||
p_node->get_gui_base()->add_child(collision_shape_2d_editor);
|
||||
}
|
||||
|
||||
CollisionShape2DEditorPlugin::~CollisionShape2DEditorPlugin() {
|
||||
|
||||
}
|
73
tools/editor/plugins/collision_shape_2d_editor_plugin.h
Normal file
73
tools/editor/plugins/collision_shape_2d_editor_plugin.h
Normal file
@ -0,0 +1,73 @@
|
||||
#ifndef COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
|
||||
#define COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
|
||||
|
||||
#include "tools/editor/editor_plugin.h"
|
||||
#include "tools/editor/editor_node.h"
|
||||
|
||||
#include "scene/2d/collision_shape_2d.h"
|
||||
|
||||
class CanvasItemEditor;
|
||||
|
||||
class CollisionShape2DEditor : public Control {
|
||||
OBJ_TYPE(CollisionShape2DEditor, Control);
|
||||
|
||||
enum ShapeType {
|
||||
CAPSULE_SHAPE,
|
||||
CIRCLE_SHAPE,
|
||||
CONCAVE_POLYGON_SHAPE,
|
||||
CONVEX_POLYGON_SHAPE,
|
||||
LINE_SHAPE,
|
||||
RAY_SHAPE,
|
||||
RECTANGLE_SHAPE,
|
||||
SEGMENT_SHAPE
|
||||
};
|
||||
|
||||
EditorNode* editor;
|
||||
UndoRedo* undo_redo;
|
||||
CanvasItemEditor* canvas_item_editor;
|
||||
CollisionShape2D* node;
|
||||
|
||||
Vector<Point2> handles;
|
||||
|
||||
int shape_type;
|
||||
int edit_handle;
|
||||
bool pressed;
|
||||
Variant original;
|
||||
|
||||
Variant get_handle_value(int idx) const;
|
||||
void set_handle(int idx, Point2& p_point);
|
||||
void commit_handle(int idx, Variant& p_org);
|
||||
|
||||
void _get_current_shape_type();
|
||||
void _canvas_draw();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
bool forward_input_event(const InputEvent& p_event);
|
||||
void edit(Node* p_node);
|
||||
|
||||
CollisionShape2DEditor(EditorNode* p_editor);
|
||||
};
|
||||
|
||||
class CollisionShape2DEditorPlugin : public EditorPlugin {
|
||||
OBJ_TYPE(CollisionShape2DEditorPlugin, EditorPlugin);
|
||||
|
||||
CollisionShape2DEditor* collision_shape_2d_editor;
|
||||
EditorNode* editor;
|
||||
|
||||
public:
|
||||
virtual bool forward_input_event(const InputEvent& p_event) { return collision_shape_2d_editor->forward_input_event(p_event); }
|
||||
|
||||
virtual String get_name() const { return "CollisionShape2D"; }
|
||||
bool has_main_screen() const { return false; }
|
||||
virtual void edit(Object* p_obj);
|
||||
virtual bool handles(Object* p_obj) const;
|
||||
virtual void make_visible(bool visible);
|
||||
|
||||
CollisionShape2DEditorPlugin(EditorNode* p_editor);
|
||||
~CollisionShape2DEditorPlugin();
|
||||
};
|
||||
|
||||
#endif //COLLISION_SHAPE_2D_EDITOR_PLUGIN_H
|
@ -305,7 +305,7 @@ void MultiMeshEditor::edit(MultiMeshInstance *p_multimesh) {
|
||||
void MultiMeshEditor::_browse(bool p_source) {
|
||||
|
||||
browsing_source=p_source;
|
||||
std->get_tree()->set_marked(node,false);
|
||||
std->get_scene_tree()->set_marked(node,false);
|
||||
std->popup_centered_ratio();
|
||||
if (p_source)
|
||||
std->set_title("Select a Source Mesh:");
|
||||
|
@ -38,11 +38,90 @@
|
||||
#include "os/file_access.h"
|
||||
#include "scene/main/viewport.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "os/input.h"
|
||||
|
||||
/*** SCRIPT EDITOR ****/
|
||||
|
||||
|
||||
class EditorScriptCodeCompletionCache : public ScriptCodeCompletionCache {
|
||||
|
||||
|
||||
struct Cache {
|
||||
uint64_t time_loaded;
|
||||
RES cache;
|
||||
};
|
||||
|
||||
Map<String,Cache> cached;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
uint64_t max_time_cache;
|
||||
int max_cache_size;
|
||||
|
||||
void cleanup() {
|
||||
|
||||
List< Map<String,Cache>::Element * > to_clean;
|
||||
|
||||
|
||||
Map<String,Cache>::Element *I=cached.front();
|
||||
while(I) {
|
||||
if ((OS::get_singleton()->get_ticks_msec()-I->get().time_loaded)>max_time_cache) {
|
||||
to_clean.push_back(I);
|
||||
}
|
||||
I=I->next();
|
||||
}
|
||||
|
||||
while(to_clean.front()) {
|
||||
cached.erase(to_clean.front()->get());
|
||||
to_clean.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
RES get_cached_resource(const String& p_path) {
|
||||
|
||||
Map<String,Cache>::Element *E=cached.find(p_path);
|
||||
if (!E) {
|
||||
|
||||
Cache c;
|
||||
c.cache=ResourceLoader::load(p_path);
|
||||
E=cached.insert(p_path,c);
|
||||
}
|
||||
|
||||
E->get().time_loaded=OS::get_singleton()->get_ticks_msec();
|
||||
|
||||
if (cached.size()>max_cache_size) {
|
||||
uint64_t older;
|
||||
Map<String,Cache>::Element *O=cached.front();
|
||||
older=O->get().time_loaded;
|
||||
Map<String,Cache>::Element *I=O;
|
||||
while(I) {
|
||||
if (I->get().time_loaded<older) {
|
||||
older = I->get().time_loaded;
|
||||
O=I;
|
||||
}
|
||||
I=I->next();
|
||||
}
|
||||
|
||||
if (O!=E) {//should never heppane..
|
||||
cached.erase(O);
|
||||
}
|
||||
}
|
||||
|
||||
return E->get().cache;
|
||||
}
|
||||
|
||||
|
||||
EditorScriptCodeCompletionCache() {
|
||||
|
||||
max_cache_size=128;
|
||||
max_time_cache=5*60*1000; //minutes, five
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#define SORT_SCRIPT_LIST
|
||||
|
||||
void ScriptEditorQuickOpen::popup(const Vector<String>& p_functions, bool p_dontclear) {
|
||||
|
||||
popup_centered_ratio(0.6);
|
||||
@ -118,6 +197,8 @@ void ScriptEditorQuickOpen::_notification(int p_what) {
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
connect("confirmed",this,"_confirmed");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,8 +367,19 @@ void ScriptTextEditor::reload_text() {
|
||||
|
||||
ERR_FAIL_COND(script.is_null()) ;
|
||||
|
||||
get_text_edit()->set_text(script->get_source_code());
|
||||
get_text_edit()->clear_undo_history();
|
||||
TextEdit *te = get_text_edit();
|
||||
int column = te->cursor_get_column();
|
||||
int row = te->cursor_get_line();
|
||||
int h = te->get_h_scroll();
|
||||
int v = te->get_v_scroll();
|
||||
|
||||
te->set_text(script->get_source_code());
|
||||
te->clear_undo_history();
|
||||
te->cursor_set_line(row);
|
||||
te->cursor_set_column(column);
|
||||
te->set_h_scroll(h);
|
||||
te->set_v_scroll(v);
|
||||
|
||||
_line_col_changed();
|
||||
|
||||
}
|
||||
@ -296,12 +388,11 @@ void ScriptTextEditor::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_READY) {
|
||||
|
||||
_update_name();
|
||||
//emit_signal("name_changed");
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptTextEditor::_update_name() {
|
||||
|
||||
String ScriptTextEditor::get_name() {
|
||||
String name;
|
||||
|
||||
if (script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) {
|
||||
@ -314,22 +405,21 @@ void ScriptTextEditor::_update_name() {
|
||||
else
|
||||
name=script->get_type()+"("+itos(script->get_instance_ID())+")";
|
||||
|
||||
|
||||
if (name!=String(get_name())) {
|
||||
|
||||
set_name(name);
|
||||
|
||||
}
|
||||
|
||||
if (!has_meta("_tab_icon")) {
|
||||
if (get_parent_control() && get_parent_control()->has_icon(script->get_type(),"EditorIcons")) {
|
||||
set_meta("_tab_icon",get_parent_control()->get_icon(script->get_type(),"EditorIcons"));
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
|
||||
}
|
||||
|
||||
Ref<Texture> ScriptTextEditor::get_icon() {
|
||||
|
||||
if (get_parent_control() && get_parent_control()->has_icon(script->get_type(),"EditorIcons")) {
|
||||
return get_parent_control()->get_icon(script->get_type(),"EditorIcons");
|
||||
}
|
||||
|
||||
return Ref<Texture>();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) {
|
||||
|
||||
ERR_FAIL_COND(!script.is_null());
|
||||
@ -344,8 +434,7 @@ void ScriptTextEditor::set_edited_script(const Ref<Script>& p_script) {
|
||||
get_text_edit()->tag_saved_version();
|
||||
|
||||
|
||||
_update_name();
|
||||
|
||||
emit_signal("name_changed");
|
||||
_line_col_changed();
|
||||
}
|
||||
|
||||
@ -384,7 +473,7 @@ void ScriptTextEditor::_validate_script() {
|
||||
te->set_line_as_marked(i,line==i);
|
||||
}
|
||||
|
||||
_update_name();
|
||||
emit_signal("name_changed");
|
||||
}
|
||||
|
||||
|
||||
@ -418,6 +507,10 @@ void ScriptTextEditor::_code_complete_script(const String& p_code, List<String>*
|
||||
}
|
||||
|
||||
}
|
||||
void ScriptTextEditor::_bind_methods() {
|
||||
|
||||
ADD_SIGNAL(MethodInfo("name_changed"));
|
||||
}
|
||||
|
||||
ScriptTextEditor::ScriptTextEditor() {
|
||||
|
||||
@ -492,11 +585,15 @@ void ScriptEditor::_close_current_tab() {
|
||||
memdelete(current);
|
||||
if (idx>=tab_container->get_child_count())
|
||||
idx=tab_container->get_child_count()-1;
|
||||
if (idx>=0)
|
||||
if (idx>=0) {
|
||||
tab_container->set_current_tab(idx);
|
||||
//script_list->select(idx);
|
||||
}
|
||||
|
||||
_update_window_menu();
|
||||
_save_files_state();
|
||||
|
||||
|
||||
_update_script_names();
|
||||
EditorNode::get_singleton()->save_layout();
|
||||
|
||||
}
|
||||
|
||||
@ -587,10 +684,10 @@ void ScriptEditor::_res_saved_callback(const Ref<Resource>& p_res) {
|
||||
ste->get_text_edit()->tag_saved_version();
|
||||
}
|
||||
|
||||
ste->_update_name();
|
||||
|
||||
}
|
||||
|
||||
_update_script_names();
|
||||
|
||||
}
|
||||
|
||||
bool ScriptEditor::_test_script_times_on_disk() {
|
||||
@ -1045,7 +1142,7 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
if (text != "")
|
||||
editor->emit_signal("request_help", text);
|
||||
} break;
|
||||
case WINDOW_CLOSE: {
|
||||
case FILE_CLOSE: {
|
||||
if (current->get_text_edit()->get_version()!=current->get_text_edit()->get_saved_version()) {
|
||||
erase_tab_confirm->set_text("Close and save changes?\n\""+current->get_name()+"\"");
|
||||
erase_tab_confirm->popup_centered_minsize();
|
||||
@ -1057,16 +1154,18 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
|
||||
if (tab_container->get_current_tab()>0) {
|
||||
tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()-1);
|
||||
script_list->call_deferred("select",tab_container->get_current_tab()-1);
|
||||
tab_container->move_child(current,tab_container->get_current_tab()-1);
|
||||
_update_window_menu();
|
||||
_update_script_names();
|
||||
}
|
||||
} break;
|
||||
case WINDOW_MOVE_RIGHT: {
|
||||
|
||||
if (tab_container->get_current_tab()<tab_container->get_child_count()-1) {
|
||||
tab_container->call_deferred("set_current_tab",tab_container->get_current_tab()+1);
|
||||
script_list->call_deferred("select",tab_container->get_current_tab()+1);
|
||||
tab_container->move_child(current,tab_container->get_current_tab()+1);
|
||||
_update_window_menu();
|
||||
_update_script_names();
|
||||
}
|
||||
|
||||
|
||||
@ -1076,6 +1175,8 @@ void ScriptEditor::_menu_option(int p_option) {
|
||||
if (p_option>=WINDOW_SELECT_BASE) {
|
||||
|
||||
tab_container->set_current_tab(p_option-WINDOW_SELECT_BASE);
|
||||
script_list->select(p_option-WINDOW_SELECT_BASE);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1096,6 +1197,8 @@ void ScriptEditor::_notification(int p_what) {
|
||||
editor->connect("stop_pressed",this,"_editor_stop");
|
||||
editor->connect("script_add_function_request",this,"_add_callback");
|
||||
editor->connect("resource_saved",this,"_res_saved_callback");
|
||||
script_list->connect("item_selected",this,"_script_selected");
|
||||
script_split->connect("dragged",this,"_script_split_dragged");
|
||||
autosave_timer->connect("timeout",this,"_autosave_scripts");
|
||||
{
|
||||
float autosave_time = EditorSettings::get_singleton()->get("text_editor/autosave_interval_secs");
|
||||
@ -1113,7 +1216,8 @@ void ScriptEditor::_notification(int p_what) {
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_READY) {
|
||||
_update_window_menu();
|
||||
|
||||
get_tree()->connect("tree_changed",this,"_tree_changed");
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
@ -1153,10 +1257,11 @@ static const Node * _find_node_with_script(const Node* p_node, const RefPtr & p_
|
||||
|
||||
Dictionary ScriptEditor::get_state() const {
|
||||
|
||||
apply_scripts();
|
||||
|
||||
// apply_scripts();
|
||||
|
||||
Dictionary state;
|
||||
|
||||
#if 0
|
||||
Array paths;
|
||||
int open=-1;
|
||||
|
||||
@ -1189,12 +1294,12 @@ Dictionary ScriptEditor::get_state() const {
|
||||
if (open!=-1)
|
||||
state["current"]=open;
|
||||
|
||||
|
||||
#endif
|
||||
return state;
|
||||
}
|
||||
void ScriptEditor::set_state(const Dictionary& p_state) {
|
||||
|
||||
|
||||
#if 0
|
||||
print_line("attempt set state: "+String(Variant(p_state)));
|
||||
|
||||
if (!p_state.has("sources"))
|
||||
@ -1231,6 +1336,7 @@ void ScriptEditor::set_state(const Dictionary& p_state) {
|
||||
if (p_state.has("current")) {
|
||||
tab_container->set_current_tab(p_state["current"]);
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
void ScriptEditor::clear() {
|
||||
@ -1254,67 +1360,16 @@ void ScriptEditor::clear() {
|
||||
int idx = tab_container->get_current_tab();
|
||||
if (idx>=tab_container->get_child_count())
|
||||
idx=tab_container->get_child_count()-1;
|
||||
if (idx>=0)
|
||||
if (idx>=0) {
|
||||
tab_container->set_current_tab(idx);
|
||||
|
||||
_update_window_menu();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditor::_save_files_state() {
|
||||
|
||||
return; //no thank you
|
||||
|
||||
String rpath="_open_scripts_"+Globals::get_singleton()->get_resource_path();
|
||||
rpath=rpath.replace("\\","_-_");
|
||||
rpath=rpath.replace("/","_-_");
|
||||
rpath=rpath.replace(":","_");
|
||||
|
||||
Vector<String> scripts;
|
||||
|
||||
for(int i=0;i<tab_container->get_child_count();i++) {
|
||||
|
||||
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
|
||||
if (!ste)
|
||||
continue;
|
||||
|
||||
|
||||
Ref<Script> script = ste->get_edited_script();
|
||||
if (script->get_path()!="" && script->get_path().find("local://")==-1 && script->get_path().find("::")==-1) {
|
||||
|
||||
|
||||
scripts.push_back(script->get_path());
|
||||
}
|
||||
script_list->select( script_list->find_metadata(idx) );
|
||||
}
|
||||
|
||||
|
||||
EditorSettings::get_singleton()->set(rpath,scripts);
|
||||
EditorSettings::get_singleton()->save();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditor::_load_files_state() {
|
||||
return;
|
||||
|
||||
String rpath="_open_scripts_"+Globals::get_singleton()->get_resource_path();
|
||||
rpath=rpath.replace("\\","_-_");
|
||||
rpath=rpath.replace("/","_-_");
|
||||
rpath=rpath.replace(":","_");
|
||||
|
||||
if (EditorSettings::get_singleton()->has(rpath)) {
|
||||
|
||||
Vector<String> open_files=EditorSettings::get_singleton()->get("rpath");
|
||||
for(int i=0;i<open_files.size();i++) {
|
||||
Ref<Script> scr = ResourceLoader::load(open_files[i]);
|
||||
if (!scr.is_valid())
|
||||
continue;
|
||||
|
||||
editor->edit_resource(scr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditor::get_breakpoints(List<String> *p_breakpoints) {
|
||||
|
||||
@ -1360,11 +1415,18 @@ void ScriptEditor::_bind_methods() {
|
||||
ObjectTypeDB::bind_method("_get_debug_tooltip",&ScriptEditor::_get_debug_tooltip);
|
||||
ObjectTypeDB::bind_method("_autosave_scripts",&ScriptEditor::_autosave_scripts);
|
||||
ObjectTypeDB::bind_method("_editor_settings_changed",&ScriptEditor::_editor_settings_changed);
|
||||
ObjectTypeDB::bind_method("_update_script_names",&ScriptEditor::_update_script_names);
|
||||
ObjectTypeDB::bind_method("_tree_changed",&ScriptEditor::_tree_changed);
|
||||
ObjectTypeDB::bind_method("_script_selected",&ScriptEditor::_script_selected);
|
||||
ObjectTypeDB::bind_method("_script_split_dragged",&ScriptEditor::_script_split_dragged);
|
||||
}
|
||||
|
||||
|
||||
void ScriptEditor::ensure_focus_current() {
|
||||
|
||||
if (!is_inside_tree())
|
||||
return;
|
||||
|
||||
int cidx = tab_container->get_current_tab();
|
||||
if (cidx<0 || cidx>=tab_container->get_tab_count());
|
||||
Control *c = tab_container->get_child(cidx)->cast_to<Control>();
|
||||
@ -1376,6 +1438,13 @@ void ScriptEditor::ensure_focus_current() {
|
||||
ste->get_text_edit()->grab_focus();
|
||||
}
|
||||
|
||||
void ScriptEditor::_script_selected(int p_idx) {
|
||||
|
||||
grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
|
||||
tab_container->set_current_tab(script_list->get_item_metadata(p_idx));
|
||||
grab_focus_block=false;
|
||||
}
|
||||
|
||||
void ScriptEditor::ensure_select_current() {
|
||||
|
||||
|
||||
@ -1386,8 +1455,66 @@ void ScriptEditor::ensure_select_current() {
|
||||
return;
|
||||
Ref<Script> script = ste->get_edited_script();
|
||||
|
||||
ste->get_text_edit()->grab_focus();
|
||||
if (!grab_focus_block && is_inside_tree())
|
||||
ste->get_text_edit()->grab_focus();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditor::_find_scripts(Node* p_base, Node* p_current, Set<Ref<Script> > &used) {
|
||||
if (p_current!=p_base && p_current->get_owner()!=p_base)
|
||||
return;
|
||||
|
||||
if (p_current->get_script_instance()) {
|
||||
Ref<Script> scr = p_current->get_script();
|
||||
if (scr.is_valid())
|
||||
used.insert(scr);
|
||||
}
|
||||
|
||||
for(int i=0;i<p_current->get_child_count();i++) {
|
||||
_find_scripts(p_base,p_current->get_child(i),used);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ScriptEditor::_update_script_names() {
|
||||
|
||||
waiting_update_names=false;
|
||||
Set<Ref<Script> > used;
|
||||
Node* edited = EditorNode::get_singleton()->get_edited_scene();
|
||||
if (edited) {
|
||||
_find_scripts(edited,edited,used);
|
||||
}
|
||||
|
||||
script_list->clear();
|
||||
for(int i=0;i<tab_container->get_child_count();i++) {
|
||||
|
||||
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
|
||||
if (!ste)
|
||||
continue;
|
||||
|
||||
String script = ste->get_name();
|
||||
Ref<Texture> icon = ste->get_icon();
|
||||
String path = ste->get_edited_script()->get_path();
|
||||
script_list->add_item(script,icon);
|
||||
|
||||
int index = script_list->get_item_count()-1;
|
||||
|
||||
script_list->set_item_tooltip(index,path);
|
||||
script_list->set_item_metadata(index,i);
|
||||
if (used.has(ste->get_edited_script())) {
|
||||
|
||||
script_list->set_item_custom_bg_color(index,Color(88/255.0,88/255.0,60/255.0));
|
||||
}
|
||||
if (tab_container->get_current_tab()==index) {
|
||||
script_list->select(index);
|
||||
}
|
||||
}
|
||||
|
||||
script_list->sort_items_by_text();
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditor::edit(const Ref<Script>& p_script) {
|
||||
@ -1425,9 +1552,13 @@ void ScriptEditor::edit(const Ref<Script>& p_script) {
|
||||
|
||||
if (ste->get_edited_script()==p_script) {
|
||||
|
||||
if (tab_container->get_current_tab()!=i)
|
||||
tab_container->set_current_tab(i);
|
||||
ste->get_text_edit()->grab_focus();
|
||||
if (!EditorNode::get_singleton()->is_changing_scene()) {
|
||||
if (tab_container->get_current_tab()!=i) {
|
||||
tab_container->set_current_tab(i);
|
||||
script_list->select( script_list->find_metadata(i) );
|
||||
}
|
||||
ste->get_text_edit()->grab_focus();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -1440,9 +1571,13 @@ void ScriptEditor::edit(const Ref<Script>& p_script) {
|
||||
tab_container->add_child(ste);
|
||||
tab_container->set_current_tab(tab_container->get_tab_count()-1);
|
||||
|
||||
_update_window_menu();
|
||||
_save_files_state();
|
||||
|
||||
|
||||
_update_script_names();
|
||||
ste->connect("name_changed",this,"_update_script_names");
|
||||
if (!restoring_layout) {
|
||||
EditorNode::get_singleton()->save_layout();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditor::save_external_data() {
|
||||
@ -1502,51 +1637,6 @@ void ScriptEditor::_editor_stop() {
|
||||
debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true );
|
||||
}
|
||||
|
||||
void ScriptEditor::_update_window_menu() {
|
||||
|
||||
int idx=0;
|
||||
for(int i=0;i<tab_container->get_child_count();i++) {
|
||||
|
||||
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
|
||||
if (!ste)
|
||||
continue;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (idx==0) {
|
||||
window_menu->set_disabled(true);
|
||||
edit_menu->set_disabled(true);
|
||||
search_menu->set_disabled(true);
|
||||
return;
|
||||
} else {
|
||||
|
||||
window_menu->set_disabled(false);
|
||||
edit_menu->set_disabled(false);
|
||||
search_menu->set_disabled(false);
|
||||
}
|
||||
|
||||
window_menu->get_popup()->clear();
|
||||
window_menu->get_popup()->add_item("Close",WINDOW_CLOSE,KEY_MASK_CMD|KEY_W);
|
||||
window_menu->get_popup()->add_separator();
|
||||
window_menu->get_popup()->add_item("Move Left",WINDOW_MOVE_LEFT,KEY_MASK_CMD|KEY_MASK_ALT|KEY_LEFT);
|
||||
window_menu->get_popup()->add_item("Move Right",WINDOW_MOVE_RIGHT,KEY_MASK_CMD|KEY_MASK_ALT|KEY_RIGHT);
|
||||
window_menu->get_popup()->add_separator();
|
||||
|
||||
idx=0;
|
||||
for(int i=0;i<tab_container->get_child_count();i++) {
|
||||
|
||||
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
|
||||
if (!ste)
|
||||
continue;
|
||||
String n = ste->get_name();
|
||||
uint32_t accel=0;
|
||||
if (idx<9) {
|
||||
accel=KEY_MASK_ALT|KEY_MASK_CMD|(KEY_1+idx);
|
||||
}
|
||||
window_menu->get_popup()->add_item(n,WINDOW_SELECT_BASE+idx,accel);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const StringArray& p_args) {
|
||||
|
||||
@ -1582,6 +1672,8 @@ void ScriptEditor::_add_callback(Object *p_obj, const String& p_function, const
|
||||
ste->get_text_edit()->cursor_set_line(pos);
|
||||
ste->get_text_edit()->cursor_set_column(1);
|
||||
|
||||
script_list->select( script_list->find_metadata(i) );
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
@ -1607,8 +1699,81 @@ void ScriptEditor::_autosave_scripts() {
|
||||
save_external_data();
|
||||
}
|
||||
|
||||
void ScriptEditor::_tree_changed() {
|
||||
|
||||
if (waiting_update_names)
|
||||
return;
|
||||
|
||||
waiting_update_names=true;
|
||||
call_deferred("_update_script_names");
|
||||
}
|
||||
|
||||
void ScriptEditor::_script_split_dragged(float) {
|
||||
|
||||
EditorNode::get_singleton()->save_layout();
|
||||
}
|
||||
|
||||
void ScriptEditor::set_window_layout(Ref<ConfigFile> p_layout) {
|
||||
|
||||
if (!bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!p_layout->has_section_key("ScriptEditor","open_scripts"))
|
||||
return;
|
||||
|
||||
Array scripts = p_layout->get_value("ScriptEditor","open_scripts");
|
||||
|
||||
restoring_layout=true;
|
||||
|
||||
for(int i=0;i<scripts.size();i++) {
|
||||
|
||||
String path = scripts[i];
|
||||
Ref<Script> scr = ResourceLoader::load(path);
|
||||
if (scr.is_valid()) {
|
||||
edit(scr);
|
||||
}
|
||||
}
|
||||
|
||||
if (p_layout->has_section_key("ScriptEditor","split_offset")) {
|
||||
script_split->set_split_offset(p_layout->get_value("ScriptEditor","split_offset"));
|
||||
}
|
||||
|
||||
|
||||
restoring_layout=false;
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditor::get_window_layout(Ref<ConfigFile> p_layout) {
|
||||
|
||||
Array scripts;
|
||||
|
||||
for(int i=0;i<tab_container->get_child_count();i++) {
|
||||
|
||||
ScriptTextEditor *ste = tab_container->get_child(i)->cast_to<ScriptTextEditor>();
|
||||
if (!ste)
|
||||
continue;
|
||||
|
||||
String path = ste->get_edited_script()->get_path();
|
||||
if (!path.is_resource_file())
|
||||
continue;
|
||||
|
||||
scripts.push_back(path);
|
||||
|
||||
}
|
||||
|
||||
p_layout->set_value("ScriptEditor","open_scripts",scripts);
|
||||
p_layout->set_value("ScriptEditor","split_offset",script_split->get_split_offset());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
||||
|
||||
completion_cache = memnew( EditorScriptCodeCompletionCache );
|
||||
restoring_layout=false;
|
||||
waiting_update_names=false;
|
||||
editor=p_editor;
|
||||
|
||||
menu_hb = memnew( HBoxContainer );
|
||||
@ -1618,17 +1783,32 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
||||
add_child(v_split);
|
||||
v_split->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
script_split = memnew( HSplitContainer );
|
||||
v_split->add_child(script_split);
|
||||
script_split->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
script_list = memnew( ItemList );
|
||||
script_split->add_child(script_list);
|
||||
script_list->set_custom_minimum_size(Size2(70,0));
|
||||
script_split->set_split_offset(70);
|
||||
|
||||
tab_container = memnew( TabContainer );
|
||||
v_split->add_child(tab_container);
|
||||
tab_container->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
tab_container->set_tabs_visible(false);
|
||||
script_split->add_child(tab_container);
|
||||
|
||||
|
||||
tab_container->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
|
||||
file_menu = memnew( MenuButton );
|
||||
menu_hb->add_child(file_menu);
|
||||
file_menu->set_text("File");
|
||||
file_menu->get_popup()->add_item("Open",FILE_OPEN);
|
||||
file_menu->get_popup()->add_separator();
|
||||
file_menu->get_popup()->add_item("Save",FILE_SAVE,KEY_MASK_ALT|KEY_MASK_CMD|KEY_S);
|
||||
file_menu->get_popup()->add_item("Save As..",FILE_SAVE_AS);
|
||||
file_menu->get_popup()->add_item("Save All",FILE_SAVE_ALL,KEY_MASK_CMD|KEY_MASK_SHIFT|KEY_S);
|
||||
file_menu->get_popup()->add_separator();
|
||||
file_menu->get_popup()->add_item("Close",FILE_CLOSE,KEY_MASK_CMD|KEY_W);
|
||||
file_menu->get_popup()->connect("item_pressed", this,"_menu_option");
|
||||
|
||||
edit_menu = memnew( MenuButton );
|
||||
@ -1690,6 +1870,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
||||
debug_menu->get_popup()->set_item_disabled( debug_menu->get_popup()->get_item_index(DEBUG_CONTINUE), true );
|
||||
|
||||
|
||||
#if 0
|
||||
window_menu = memnew( MenuButton );
|
||||
menu_hb->add_child(window_menu);
|
||||
window_menu->set_text("Window");
|
||||
@ -1700,6 +1881,8 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
||||
window_menu->get_popup()->add_separator();
|
||||
window_menu->get_popup()->connect("item_pressed", this,"_menu_option");
|
||||
|
||||
#endif
|
||||
|
||||
help_menu = memnew( MenuButton );
|
||||
menu_hb->add_child(help_menu);
|
||||
help_menu->set_text("Help");
|
||||
@ -1762,11 +1945,18 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
|
||||
autosave_timer->set_one_shot(false);
|
||||
add_child(autosave_timer);
|
||||
|
||||
grab_focus_block=false;
|
||||
|
||||
// debugger_gui->hide();
|
||||
|
||||
}
|
||||
|
||||
|
||||
ScriptEditor::~ScriptEditor() {
|
||||
|
||||
memdelete(completion_cache);
|
||||
}
|
||||
|
||||
void ScriptEditorPlugin::edit(Object *p_object) {
|
||||
|
||||
if (!p_object->cast_to<Script>())
|
||||
@ -1826,20 +2016,24 @@ void ScriptEditorPlugin::apply_changes() {
|
||||
|
||||
void ScriptEditorPlugin::restore_global_state() {
|
||||
|
||||
if (bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) {
|
||||
script_editor->_load_files_state();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorPlugin::save_global_state() {
|
||||
|
||||
if (bool(EDITOR_DEF("text_editor/restore_scripts_on_load",true))) {
|
||||
script_editor->_save_files_state();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ScriptEditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
|
||||
|
||||
script_editor->set_window_layout(p_layout);
|
||||
}
|
||||
|
||||
void ScriptEditorPlugin::get_window_layout(Ref<ConfigFile> p_layout){
|
||||
|
||||
script_editor->get_window_layout(p_layout);
|
||||
}
|
||||
|
||||
|
||||
void ScriptEditorPlugin::get_breakpoints(List<String> *p_breakpoints) {
|
||||
|
||||
|
||||
|
@ -33,12 +33,13 @@
|
||||
#include "scene/gui/tab_container.h"
|
||||
#include "scene/gui/text_edit.h"
|
||||
#include "scene/gui/menu_button.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
#include "scene/gui/tree.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "script_language.h"
|
||||
#include "tools/editor/code_editor.h"
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
#include "scene/gui/item_list.h"
|
||||
|
||||
class ScriptEditorQuickOpen : public ConfirmationDialog {
|
||||
|
||||
@ -88,6 +89,7 @@ protected:
|
||||
virtual void _code_complete_script(const String& p_code, List<String>* r_options);
|
||||
virtual void _load_theme_settings();
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
|
||||
public:
|
||||
@ -97,12 +99,15 @@ public:
|
||||
Vector<String> get_functions() ;
|
||||
void set_edited_script(const Ref<Script>& p_script);
|
||||
void reload_text();
|
||||
void _update_name();
|
||||
String get_name() ;
|
||||
Ref<Texture> get_icon() ;
|
||||
|
||||
ScriptTextEditor();
|
||||
|
||||
};
|
||||
|
||||
class EditorScriptCodeCompletionCache;
|
||||
|
||||
class ScriptEditor : public VBoxContainer {
|
||||
|
||||
OBJ_TYPE(ScriptEditor, VBoxContainer );
|
||||
@ -115,6 +120,7 @@ class ScriptEditor : public VBoxContainer {
|
||||
FILE_SAVE,
|
||||
FILE_SAVE_AS,
|
||||
FILE_SAVE_ALL,
|
||||
FILE_CLOSE,
|
||||
EDIT_UNDO,
|
||||
EDIT_REDO,
|
||||
EDIT_CUT,
|
||||
@ -123,12 +129,12 @@ class ScriptEditor : public VBoxContainer {
|
||||
EDIT_SELECT_ALL,
|
||||
EDIT_COMPLETE,
|
||||
EDIT_AUTO_INDENT,
|
||||
EDIT_TOGGLE_COMMENT,
|
||||
EDIT_MOVE_LINE_UP,
|
||||
EDIT_MOVE_LINE_DOWN,
|
||||
EDIT_INDENT_RIGHT,
|
||||
EDIT_INDENT_LEFT,
|
||||
EDIT_CLONE_DOWN,
|
||||
EDIT_TOGGLE_COMMENT,
|
||||
EDIT_MOVE_LINE_UP,
|
||||
EDIT_MOVE_LINE_DOWN,
|
||||
EDIT_INDENT_RIGHT,
|
||||
EDIT_INDENT_LEFT,
|
||||
EDIT_CLONE_DOWN,
|
||||
SEARCH_FIND,
|
||||
SEARCH_FIND_NEXT,
|
||||
SEARCH_REPLACE,
|
||||
@ -140,8 +146,7 @@ class ScriptEditor : public VBoxContainer {
|
||||
DEBUG_BREAK,
|
||||
DEBUG_CONTINUE,
|
||||
DEBUG_SHOW,
|
||||
HELP_CONTEXTUAL,
|
||||
WINDOW_CLOSE,
|
||||
HELP_CONTEXTUAL,
|
||||
WINDOW_MOVE_LEFT,
|
||||
WINDOW_MOVE_RIGHT,
|
||||
WINDOW_SELECT_BASE=100
|
||||
@ -151,17 +156,19 @@ class ScriptEditor : public VBoxContainer {
|
||||
MenuButton *file_menu;
|
||||
MenuButton *edit_menu;
|
||||
MenuButton *search_menu;
|
||||
MenuButton *window_menu;
|
||||
MenuButton *debug_menu;
|
||||
MenuButton *help_menu;
|
||||
Timer *autosave_timer;
|
||||
uint64_t idle;
|
||||
|
||||
ItemList *script_list;
|
||||
HSplitContainer *script_split;
|
||||
TabContainer *tab_container;
|
||||
FindReplaceDialog *find_replace_dialog;
|
||||
GotoLineDialog *goto_line_dialog;
|
||||
ConfirmationDialog *erase_tab_confirm;
|
||||
ScriptEditorDebugger* debugger;
|
||||
ToolButton *scripts_visible;
|
||||
|
||||
void _tab_changed(int p_which);
|
||||
void _menu_option(int p_optin);
|
||||
@ -171,6 +178,8 @@ class ScriptEditor : public VBoxContainer {
|
||||
|
||||
VSplitContainer *v_split;
|
||||
|
||||
bool restoring_layout;
|
||||
|
||||
String _get_debug_tooltip(const String&p_text,Node *_ste);
|
||||
|
||||
void _resave_scripts(const String& p_str);
|
||||
@ -180,8 +189,11 @@ class ScriptEditor : public VBoxContainer {
|
||||
|
||||
void _close_current_tab();
|
||||
|
||||
bool grab_focus_block;
|
||||
|
||||
ScriptEditorQuickOpen *quick_open;
|
||||
|
||||
EditorScriptCodeCompletionCache *completion_cache;
|
||||
|
||||
void _editor_play();
|
||||
void _editor_pause();
|
||||
@ -199,6 +211,18 @@ class ScriptEditor : public VBoxContainer {
|
||||
void _editor_settings_changed();
|
||||
void _autosave_scripts();
|
||||
|
||||
void _update_script_names();
|
||||
|
||||
void _script_selected(int p_idx);
|
||||
|
||||
void _find_scripts(Node* p_base, Node* p_current,Set<Ref<Script> >& used);
|
||||
|
||||
void _tree_changed();
|
||||
|
||||
void _script_split_dragged(float);
|
||||
|
||||
bool waiting_update_names;
|
||||
|
||||
static ScriptEditor *script_editor;
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
@ -206,9 +230,6 @@ protected:
|
||||
public:
|
||||
|
||||
static ScriptEditor *get_singleton() { return script_editor; }
|
||||
void _save_files_state();
|
||||
void _load_files_state();
|
||||
|
||||
|
||||
void ensure_focus_current();
|
||||
void apply_scripts() const;
|
||||
@ -222,11 +243,15 @@ public:
|
||||
|
||||
void get_breakpoints(List<String> *p_breakpoints);
|
||||
|
||||
void swap_lines(TextEdit *tx, int line1, int line2);
|
||||
void swap_lines(TextEdit *tx, int line1, int line2);
|
||||
|
||||
void save_external_data();
|
||||
|
||||
void set_window_layout(Ref<ConfigFile> p_layout);
|
||||
void get_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
||||
ScriptEditor(EditorNode *p_editor);
|
||||
~ScriptEditor();
|
||||
};
|
||||
|
||||
class ScriptEditorPlugin : public EditorPlugin {
|
||||
@ -254,6 +279,9 @@ public:
|
||||
virtual void restore_global_state();
|
||||
virtual void save_global_state();
|
||||
|
||||
virtual void set_window_layout(Ref<ConfigFile> p_layout);
|
||||
virtual void get_window_layout(Ref<ConfigFile> p_layout);
|
||||
|
||||
virtual void get_breakpoints(List<String> *p_breakpoints);
|
||||
|
||||
|
||||
|
@ -71,22 +71,19 @@ void TileMapEditor::_canvas_mouse_exit() {
|
||||
}
|
||||
|
||||
int TileMapEditor::get_selected_tile() const {
|
||||
|
||||
TreeItem *item = palette->get_selected();
|
||||
if (!item)
|
||||
int item = palette->get_current();
|
||||
if (item==-1)
|
||||
return TileMap::INVALID_CELL;
|
||||
return item->get_metadata(0);
|
||||
return palette->get_item_metadata(item);
|
||||
}
|
||||
|
||||
void TileMapEditor::set_selected_tile(int p_tile) {
|
||||
TreeItem *item = palette->get_root()->get_children();
|
||||
while (item) {
|
||||
if ((int)item->get_metadata(0) == p_tile) {
|
||||
item->select(0);
|
||||
palette->ensure_cursor_is_visible();
|
||||
for (int i = 0; i < palette->get_item_count(); i++) {
|
||||
if (palette->get_item_metadata(i).operator int() == p_tile) {
|
||||
palette->select(i,true);
|
||||
palette->ensure_current_is_visible();
|
||||
break;
|
||||
}
|
||||
item = item->get_next();
|
||||
}
|
||||
}
|
||||
|
||||
@ -95,7 +92,7 @@ void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_f
|
||||
ERR_FAIL_COND(!node);
|
||||
node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose);
|
||||
}
|
||||
|
||||
|
||||
void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) {
|
||||
|
||||
ERR_FAIL_COND(!node);
|
||||
@ -120,42 +117,78 @@ void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bo
|
||||
|
||||
}
|
||||
|
||||
void TileMapEditor::_set_display_mode(int p_mode) {
|
||||
if (display_mode == p_mode) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p_mode) {
|
||||
case DISPLAY_THUMBNAIL: {
|
||||
button_thumbnail->set_pressed(true);
|
||||
button_list->set_pressed(false);
|
||||
} break;
|
||||
case DISPLAY_LIST: {
|
||||
button_thumbnail->set_pressed(false);
|
||||
button_list->set_pressed(true);
|
||||
} break;
|
||||
}
|
||||
|
||||
display_mode = p_mode;
|
||||
|
||||
_update_palette();
|
||||
}
|
||||
|
||||
void TileMapEditor::_update_palette() {
|
||||
|
||||
if (!node)
|
||||
return;
|
||||
|
||||
palette->clear();;
|
||||
palette->clear();
|
||||
|
||||
Ref<TileSet> tileset=node->get_tileset();
|
||||
if (!tileset.is_valid())
|
||||
return;
|
||||
|
||||
|
||||
TreeItem *root = palette->create_item();
|
||||
palette->set_hide_root(true);
|
||||
List<int> tiles;
|
||||
tileset->get_tile_list(&tiles);
|
||||
|
||||
if (display_mode == DISPLAY_THUMBNAIL) {
|
||||
palette->set_max_columns(0);
|
||||
palette->set_icon_mode(ItemList::ICON_MODE_TOP);
|
||||
} else if (display_mode == DISPLAY_LIST) {
|
||||
palette->set_max_columns(1);
|
||||
palette->set_icon_mode(ItemList::ICON_MODE_LEFT);
|
||||
}
|
||||
|
||||
palette->set_max_text_lines(2);
|
||||
|
||||
for(List<int>::Element *E=tiles.front();E;E=E->next()) {
|
||||
palette->add_item("");
|
||||
|
||||
TreeItem *tile = palette->create_item(root);
|
||||
|
||||
tile->set_icon_max_width(0,64);
|
||||
Ref<Texture> tex = tileset->tile_get_texture(E->get());
|
||||
|
||||
if (tex.is_valid()) {
|
||||
tile->set_icon(0,tex);
|
||||
Rect2 region = tileset->tile_get_region(E->get());
|
||||
if (region!=Rect2())
|
||||
tile->set_icon_region(0,region);
|
||||
|
||||
} else if (tileset->tile_get_name(E->get())!="")
|
||||
tile->set_text(0,tileset->tile_get_name(E->get()));
|
||||
else
|
||||
tile->set_text(0,"#"+itos(E->get()));
|
||||
if (!region.has_no_area()) {
|
||||
Image data = VS::get_singleton()->texture_get_data(tex->get_rid());
|
||||
|
||||
tile->set_metadata(0,E->get());
|
||||
Ref<ImageTexture> img = memnew( ImageTexture );
|
||||
img->create_from_image(data.get_rect(region));
|
||||
|
||||
palette->set_item_icon(palette->get_item_count()-1, img);
|
||||
} else {
|
||||
palette->set_item_icon(palette->get_item_count()-1,tex);
|
||||
}
|
||||
}
|
||||
|
||||
if (tileset->tile_get_name(E->get())!="") {
|
||||
palette->set_item_text(palette->get_item_count()-1, tileset->tile_get_name(E->get()));
|
||||
} else {
|
||||
palette->set_item_text(palette->get_item_count()-1, "#"+itos(E->get()));
|
||||
}
|
||||
|
||||
palette->set_item_metadata(palette->get_item_count()-1, E->get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -387,7 +420,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
||||
}
|
||||
|
||||
if (tool==TOOL_ERASING) {
|
||||
Point2i local =over_tile;
|
||||
Point2i local =over_tile;
|
||||
if (!paint_undo.has(over_tile)) {
|
||||
paint_undo[over_tile]=_get_op_from_cell(over_tile);
|
||||
}
|
||||
@ -641,7 +674,7 @@ void TileMapEditor::_canvas_draw() {
|
||||
Ref<Texture> t = ts->tile_get_texture(st);
|
||||
if (t.is_valid()) {
|
||||
Vector2 from = node->map_to_world(over_tile)+node->get_cell_draw_offset();
|
||||
Rect2 r = ts->tile_get_region(st);
|
||||
Rect2 r = ts->tile_get_region(st);
|
||||
Size2 sc = xform.get_scale();
|
||||
if (mirror_x->is_pressed())
|
||||
sc.x*=-1.0;
|
||||
@ -755,7 +788,7 @@ void TileMapEditor::_bind_methods() {
|
||||
ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed);
|
||||
ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons);
|
||||
ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_set_display_mode","mode"),&TileMapEditor::_set_display_mode);
|
||||
}
|
||||
|
||||
TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos)
|
||||
@ -777,7 +810,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) {
|
||||
//ERR_FAIL_NULL(p_button);
|
||||
ToolButton *b=p_button->cast_to<ToolButton>();
|
||||
//ERR_FAIL_COND(!b);
|
||||
|
||||
|
||||
mirror_x->set_block_signals(true);
|
||||
mirror_y->set_block_signals(true);
|
||||
transpose->set_block_signals(true);
|
||||
@ -785,7 +818,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) {
|
||||
rotate_90->set_block_signals(true);
|
||||
rotate_180->set_block_signals(true);
|
||||
rotate_270->set_block_signals(true);
|
||||
|
||||
|
||||
if (b == rotate_0) {
|
||||
mirror_x->set_pressed(false);
|
||||
mirror_y->set_pressed(false);
|
||||
@ -806,7 +839,7 @@ void TileMapEditor::_update_transform_buttons(Object *p_button) {
|
||||
mirror_y->set_pressed(true);
|
||||
transpose->set_pressed(true);
|
||||
}
|
||||
|
||||
|
||||
rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed());
|
||||
rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed());
|
||||
rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed());
|
||||
@ -833,8 +866,27 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
||||
ec->set_custom_minimum_size(Size2(mw,0));
|
||||
add_child(ec);
|
||||
|
||||
HBoxContainer *hb = memnew( HBoxContainer );
|
||||
add_child(hb);
|
||||
hb->set_h_size_flags(SIZE_EXPAND_FILL);
|
||||
hb->add_spacer(true);
|
||||
|
||||
button_thumbnail = memnew( ToolButton );
|
||||
button_thumbnail->set_toggle_mode(true);
|
||||
button_thumbnail->set_pressed(true);
|
||||
button_thumbnail->set_icon(p_editor->get_gui_base()->get_icon("FileThumbnail","EditorIcons"));
|
||||
hb->add_child(button_thumbnail);
|
||||
button_thumbnail->connect("pressed", this, "_set_display_mode", varray(DISPLAY_THUMBNAIL));
|
||||
|
||||
button_list = memnew( ToolButton );
|
||||
button_list->set_toggle_mode(true);
|
||||
button_list->set_pressed(false);
|
||||
button_list->set_icon(p_editor->get_gui_base()->get_icon("FileList","EditorIcons"));
|
||||
hb->add_child(button_list);
|
||||
button_list->connect("pressed", this, "_set_display_mode", varray(DISPLAY_LIST));
|
||||
|
||||
// Add tile palette
|
||||
palette = memnew( Tree );
|
||||
palette = memnew( ItemList );
|
||||
palette->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
add_child(palette);
|
||||
|
||||
@ -886,7 +938,7 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
||||
rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270));
|
||||
canvas_item_editor_hb->add_child(rotate_270);
|
||||
canvas_item_editor_hb->hide();
|
||||
|
||||
|
||||
rotate_0->set_pressed(true);
|
||||
tool=TOOL_NONE;
|
||||
selection_active=false;
|
||||
|
@ -55,10 +55,18 @@ class TileMapEditor : public VBoxContainer {
|
||||
TOOL_PICKING
|
||||
};
|
||||
|
||||
enum DisplayMode {
|
||||
DISPLAY_THUMBNAIL,
|
||||
DISPLAY_LIST
|
||||
};
|
||||
|
||||
Tool tool;
|
||||
Control *canvas_item_editor;
|
||||
|
||||
Tree *palette;
|
||||
int display_mode;
|
||||
ItemList *palette;
|
||||
ToolButton *button_thumbnail;
|
||||
ToolButton *button_list;
|
||||
EditorNode *editor;
|
||||
Panel *panel;
|
||||
TileMap *node;
|
||||
@ -95,6 +103,7 @@ class TileMapEditor : public VBoxContainer {
|
||||
int get_selected_tile() const;
|
||||
void set_selected_tile(int p_tile);
|
||||
|
||||
void _set_display_mode(int p_mode);
|
||||
void _update_palette();
|
||||
void _canvas_draw();
|
||||
void _menu_option(int p_option);
|
||||
|
@ -819,6 +819,7 @@ ProjectManager::ProjectManager() {
|
||||
if (!EditorSettings::get_singleton())
|
||||
EditorSettings::create();
|
||||
|
||||
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("file_dialog/show_hidden_files"));
|
||||
|
||||
set_area_as_parent_rect();
|
||||
Panel *panel = memnew( Panel );
|
||||
|
@ -1633,7 +1633,7 @@ CustomPropertyEditor::CustomPropertyEditor() {
|
||||
scene_tree = memnew( SceneTreeDialog );
|
||||
add_child(scene_tree);
|
||||
scene_tree->connect("selected", this,"_node_path_selected");
|
||||
scene_tree->get_tree()->set_show_enabled_subscene(true);
|
||||
scene_tree->get_scene_tree()->set_show_enabled_subscene(true);
|
||||
|
||||
texture_preview = memnew( TextureFrame );
|
||||
add_child( texture_preview);
|
||||
|
@ -134,6 +134,7 @@ public:
|
||||
void set_selected(Node *p_node, bool p_emit_selected=false);
|
||||
void fill_path_renames(Node* p_node, Node *p_new_parent, List<Pair<NodePath,NodePath> > *p_renames);
|
||||
void perform_node_renames(Node* p_base,List<Pair<NodePath,NodePath> > *p_renames, Map<Ref<Animation>, Set<int> > *r_rem_anims=NULL);
|
||||
SceneTreeEditor *get_tree_editor() { return scene_tree; }
|
||||
|
||||
SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelection *p_editor_selection,EditorData &p_editor_data);
|
||||
};
|
||||
|
@ -125,6 +125,9 @@ public:
|
||||
|
||||
void update_tree() { _update_tree(); }
|
||||
|
||||
|
||||
Tree* get_scene_tree() { return tree; }
|
||||
|
||||
SceneTreeEditor(bool p_label=true,bool p_can_rename=false, bool p_can_open_instance=false);
|
||||
~SceneTreeEditor();
|
||||
|
||||
@ -150,7 +153,7 @@ protected:
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
SceneTreeEditor *get_tree() { return tree; }
|
||||
SceneTreeEditor *get_scene_tree() { return tree; }
|
||||
SceneTreeDialog();
|
||||
~SceneTreeDialog();
|
||||
|
||||
|
@ -228,7 +228,7 @@ class DaeExporter:
|
||||
# imgpath="images/"+image.name+".png"
|
||||
|
||||
self.writel(S_IMGS,1,'<image id="'+imgid+'" name="'+image.name+'">')
|
||||
self.writel(S_IMGS,2,'<init_from>'+imgpath+'</init_from>"/>')
|
||||
self.writel(S_IMGS,2,'<init_from>'+imgpath+'</init_from>')
|
||||
self.writel(S_IMGS,1,'</image>')
|
||||
self.image_cache[image]=imgid
|
||||
return imgid
|
||||
|
Loading…
Reference in New Issue
Block a user