summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/resource.cpp125
-rw-r--r--core/resource.h15
-rw-r--r--scene/gui/base_button.cpp107
-rw-r--r--scene/gui/base_button.h24
-rw-r--r--scene/gui/button.h3
-rw-r--r--scene/gui/button_group.cpp3
-rw-r--r--scene/gui/button_group.h3
-rw-r--r--scene/gui/check_box.cpp8
-rw-r--r--scene/main/viewport.cpp94
-rw-r--r--scene/main/viewport.h20
-rw-r--r--scene/resources/packed_scene.cpp70
-rw-r--r--scene/resources/packed_scene.h19
-rw-r--r--tools/editor/editor_data.cpp2
-rw-r--r--tools/editor/editor_node.cpp9
-rw-r--r--tools/editor/io_plugins/editor_texture_import_plugin.cpp2
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.cpp17
-rw-r--r--tools/editor/plugins/canvas_item_editor_plugin.h3
-rw-r--r--tools/editor/plugins/theme_editor_plugin.cpp2
-rw-r--r--tools/editor/property_editor.cpp43
-rw-r--r--tools/editor/property_editor.h1
-rw-r--r--tools/editor/scene_tree_dock.cpp6
21 files changed, 481 insertions, 95 deletions
diff --git a/core/resource.cpp b/core/resource.cpp
index 7bcdd88891..9545d8c3da 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -31,6 +31,7 @@
#include <stdio.h>
#include "os/file_access.h"
#include "io/resource_loader.h"
+#include "script_language.h"
void ResourceImportMetadata::set_editor(const String& p_editor) {
@@ -201,7 +202,7 @@ void Resource::set_path(const String& p_path, bool p_take_over) {
ResourceCache::lock->write_unlock();
}
- _change_notify("resource/path");
+ _change_notify("resource_path");
_resource_path_changed();
}
@@ -225,7 +226,7 @@ int Resource::get_subindex() const{
void Resource::set_name(const String& p_name) {
name=p_name;
- _change_notify("resource/name");
+ _change_notify("resource_name");
}
String Resource::get_name() const {
@@ -257,7 +258,7 @@ void Resource::reload_from_file() {
if (!(E->get().usage&PROPERTY_USAGE_STORAGE))
continue;
- if (E->get().name=="resource/path")
+ if (E->get().name=="resource_path")
continue; //do not change path
set(E->get().name,s->get(E->get().name));
@@ -266,8 +267,51 @@ void Resource::reload_from_file() {
}
+Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache) {
+
+
+ List<PropertyInfo> plist;
+ get_property_list(&plist);
+
+
+ Resource *r = (Resource*)ClassDB::instance(get_class());
+ ERR_FAIL_COND_V(!r,Ref<Resource>());
+
+ r->local_scene=p_for_scene;
+
+ for(List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) {
+
+ if (!(E->get().usage&PROPERTY_USAGE_STORAGE))
+ continue;
+ Variant p = get(E->get().name);
+ if (p.get_type()==Variant::OBJECT) {
+
+ RES sr = p;
+ if (sr.is_valid()) {
+
+ if (sr->is_local_to_scene()) {
+ if (remap_cache.has(sr)) {
+ p=remap_cache[sr];
+ } else {
+
+
+ RES dupe = sr->duplicate_for_local_scene(p_for_scene,remap_cache);
+ p=dupe;
+ remap_cache[sr]=dupe;
+ }
+ }
+ }
+ }
+
+ r->set(E->get().name,p);
+ }
+
+ return Ref<Resource>(r);
+}
+
Ref<Resource> Resource::duplicate(bool p_subresources) {
+
List<PropertyInfo> plist;
get_property_list(&plist);
@@ -305,24 +349,6 @@ void Resource::_take_over_path(const String& p_path) {
}
-void Resource::_bind_methods() {
-
- ClassDB::bind_method(_MD("set_path","path"),&Resource::_set_path);
- ClassDB::bind_method(_MD("take_over_path","path"),&Resource::_take_over_path);
- ClassDB::bind_method(_MD("get_path"),&Resource::get_path);
- ClassDB::bind_method(_MD("set_name","name"),&Resource::set_name);
- ClassDB::bind_method(_MD("get_name"),&Resource::get_name);
- ClassDB::bind_method(_MD("get_rid"),&Resource::get_rid);
- ClassDB::bind_method(_MD("set_import_metadata","metadata"),&Resource::set_import_metadata);
- ClassDB::bind_method(_MD("get_import_metadata"),&Resource::get_import_metadata);
-
- ClassDB::bind_method(_MD("duplicate","subresources"),&Resource::duplicate,DEFVAL(false));
- ADD_SIGNAL( MethodInfo("changed") );
- ADD_GROUP("Resource","resource_");
- ADD_PROPERTY( PropertyInfo(Variant::STRING,"resource_path",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR ), _SCS("set_path"),_SCS("get_path"));
- ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"resource_name"), _SCS("set_name"),_SCS("get_name"));
-}
-
RID Resource::get_rid() const {
return RID();
@@ -394,6 +420,62 @@ uint32_t Resource::hash_edited_version() const {
#endif
+void Resource::set_local_to_scene(bool p_enable) {
+
+ local_to_scene=p_enable;
+}
+
+bool Resource::is_local_to_scene() const {
+
+ return local_to_scene;
+}
+
+Node* Resource::get_local_scene() const {
+
+ if (local_scene)
+ return local_scene;
+
+ if (_get_local_scene_func) {
+ return _get_local_scene_func();
+ }
+
+ return NULL;
+}
+
+void Resource::setup_local_to_scene() {
+
+ if (get_script_instance())
+ get_script_instance()->call("_setup_local_to_scene");
+}
+
+Node* (*Resource::_get_local_scene_func)()=NULL;
+
+
+void Resource::_bind_methods() {
+
+ ClassDB::bind_method(_MD("set_path","path"),&Resource::_set_path);
+ ClassDB::bind_method(_MD("take_over_path","path"),&Resource::_take_over_path);
+ ClassDB::bind_method(_MD("get_path"),&Resource::get_path);
+ ClassDB::bind_method(_MD("set_name","name"),&Resource::set_name);
+ ClassDB::bind_method(_MD("get_name"),&Resource::get_name);
+ ClassDB::bind_method(_MD("get_rid"),&Resource::get_rid);
+ ClassDB::bind_method(_MD("set_import_metadata","metadata"),&Resource::set_import_metadata);
+ ClassDB::bind_method(_MD("get_import_metadata"),&Resource::get_import_metadata);
+ ClassDB::bind_method(_MD("set_local_to_scene","enable"),&Resource::set_local_to_scene);
+ ClassDB::bind_method(_MD("is_local_to_scene"),&Resource::is_local_to_scene);
+ ClassDB::bind_method(_MD("get_local_scene:Node"),&Resource::get_local_scene);
+ ClassDB::bind_method(_MD("setup_local_to_scene"),&Resource::setup_local_to_scene);
+
+ ClassDB::bind_method(_MD("duplicate","subresources"),&Resource::duplicate,DEFVAL(false));
+ ADD_SIGNAL( MethodInfo("changed") );
+ ADD_GROUP("Resource","resource_");
+ ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"resource_local_to_scene" ), _SCS("set_local_to_scene"),_SCS("is_local_to_scene"));
+ ADD_PROPERTY( PropertyInfo(Variant::STRING,"resource_path",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR ), _SCS("set_path"),_SCS("get_path"));
+ ADD_PROPERTYNZ( PropertyInfo(Variant::STRING,"resource_name"), _SCS("set_name"),_SCS("get_name"));
+
+ BIND_VMETHOD( MethodInfo("_setup_local_to_scene") );
+
+}
Resource::Resource() {
@@ -402,6 +484,7 @@ Resource::Resource() {
#endif
subindex=0;
+ local_scene=NULL;
}
diff --git a/core/resource.h b/core/resource.h
index 40b6dd78a0..8b73bcdc57 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -61,6 +61,7 @@ class ResourceImportMetadata : public Reference {
Map<String,Variant> options;
StringArray _get_options() const;
+
protected:
static void _bind_methods();
@@ -82,6 +83,7 @@ public:
void get_options(List<String> *r_options) const;
+
ResourceImportMetadata();
};
@@ -108,6 +110,10 @@ friend class ResourceCache;
uint64_t last_modified_time;
#endif
+ bool local_to_scene;
+friend class SceneState;
+ Node* local_scene;
+
protected:
void emit_changed();
@@ -121,6 +127,8 @@ protected:
void _take_over_path(const String& p_path);
public:
+ static Node* (*_get_local_scene_func)(); //used by editor
+
virtual bool editor_can_reload_from_file();
virtual void reload_from_file();
@@ -137,12 +145,17 @@ public:
int get_subindex() const;
Ref<Resource> duplicate(bool p_subresources=false);
+ Ref<Resource> duplicate_for_local_scene(Node *p_scene,Map<Ref<Resource>,Ref<Resource> >& remap_cache);
+
void set_import_metadata(const Ref<ResourceImportMetadata>& p_metadata);
Ref<ResourceImportMetadata> get_import_metadata() const;
+ void set_local_to_scene(bool p_enable);
+ bool is_local_to_scene() const;
+ virtual void setup_local_to_scene();
-
+ Node* get_local_scene() const;
#ifdef TOOLS_ENABLED
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 05646320cc..45c491cd74 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -29,10 +29,23 @@
#include "base_button.h"
#include "os/keyboard.h"
#include "print_string.h"
-#include "button_group.h"
#include "scene/scene_string_names.h"
#include "scene/main/viewport.h"
+
+void BaseButton::_unpress_group() {
+
+ if (!button_group.is_valid())
+ return;
+
+ for (Set<BaseButton*>::Element *E=button_group->buttons.front();E;E=E->next()) {
+ if (E->get()==this)
+ continue;
+
+ E->get()->set_pressed(false);
+ }
+}
+
void BaseButton::_gui_input(InputEvent p_event) {
@@ -69,6 +82,8 @@ void BaseButton::_gui_input(InputEvent p_event) {
}
emit_signal("pressed");
+ _unpress_group();
+
} else {
@@ -79,6 +94,8 @@ void BaseButton::_gui_input(InputEvent p_event) {
get_script_instance()->call(SceneStringNames::get_singleton()->_pressed,NULL,0,ce);
}
emit_signal("pressed");
+ _unpress_group();
+
toggled(status.pressed);
emit_signal("toggled",status.pressed);
@@ -139,6 +156,9 @@ void BaseButton::_gui_input(InputEvent p_event) {
}
+ _unpress_group();
+
+
}
status.press_attempt=false;
@@ -212,6 +232,9 @@ void BaseButton::_gui_input(InputEvent p_event) {
}
emit_signal("toggled",status.pressed);
}
+
+ _unpress_group();
+
}
accept_event();
@@ -266,24 +289,12 @@ void BaseButton::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
- CanvasItem *ci=this;
- while(ci) {
-
- ButtonGroup *bg = ci->cast_to<ButtonGroup>();
- if (bg) {
- group=bg;
- group->_add_button(this);
- }
-
- ci=ci->get_parent_item();
- }
}
if (p_what==NOTIFICATION_EXIT_TREE) {
- if (group)
- group->_remove_button(this);
+
}
if (p_what==NOTIFICATION_VISIBILITY_CHANGED && !is_visible()) {
@@ -306,8 +317,9 @@ void BaseButton::pressed() {
void BaseButton::toggled(bool p_pressed) {
- if (get_script_instance())
+ if (get_script_instance()) {
get_script_instance()->call("toggled",p_pressed);
+ }
}
@@ -336,6 +348,11 @@ void BaseButton::set_pressed(bool p_pressed) {
return;
_change_notify("pressed");
status.pressed=p_pressed;
+
+ if (p_pressed) {
+ _unpress_group();
+
+ }
update();
}
@@ -463,6 +480,29 @@ String BaseButton::get_tooltip(const Point2& p_pos) const {
return tooltip;
}
+
+void BaseButton::set_button_group(const Ref<ButtonGroup>& p_group) {
+
+ if (button_group.is_valid()) {
+ button_group->buttons.erase(this);
+ }
+
+ button_group=p_group;
+
+ if (button_group.is_valid()) {
+ button_group->buttons.insert(this);
+ }
+
+ update(); //checkbox changes to radio if set a buttongroup
+
+}
+
+Ref<ButtonGroup> BaseButton::get_button_group() const {
+
+ return button_group;
+}
+
+
void BaseButton::_bind_methods() {
ClassDB::bind_method(_MD("_gui_input"),&BaseButton::_gui_input);
@@ -479,9 +519,13 @@ void BaseButton::_bind_methods() {
ClassDB::bind_method(_MD("get_draw_mode"),&BaseButton::get_draw_mode);
ClassDB::bind_method(_MD("set_enabled_focus_mode","mode"),&BaseButton::set_enabled_focus_mode);
ClassDB::bind_method(_MD("get_enabled_focus_mode"),&BaseButton::get_enabled_focus_mode);
+
ClassDB::bind_method(_MD("set_shortcut","shortcut"),&BaseButton::set_shortcut);
ClassDB::bind_method(_MD("get_shortcut"),&BaseButton::get_shortcut);
+ ClassDB::bind_method(_MD("set_button_group","button_group"),&BaseButton::set_button_group);
+ ClassDB::bind_method(_MD("get_button_group"),&BaseButton::get_button_group);
+
BIND_VMETHOD(MethodInfo("_pressed"));
BIND_VMETHOD(MethodInfo("_toggled",PropertyInfo(Variant::BOOL,"pressed")));
@@ -495,6 +539,7 @@ void BaseButton::_bind_methods() {
ADD_PROPERTYNZ( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press"));
ADD_PROPERTY( PropertyInfo( Variant::INT,"enabled_focus_mode", PROPERTY_HINT_ENUM, "None,Click,All" ), _SCS("set_enabled_focus_mode"), _SCS("get_enabled_focus_mode") );
ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "shortcut",PROPERTY_HINT_RESOURCE_TYPE,"ShortCut"), _SCS("set_shortcut"), _SCS("get_shortcut"));
+ ADD_PROPERTY( PropertyInfo( Variant::OBJECT, "group",PROPERTY_HINT_RESOURCE_TYPE,"ButtonGroup"), _SCS("set_button_group"), _SCS("get_button_group"));
BIND_CONSTANT( DRAW_NORMAL );
@@ -516,7 +561,11 @@ BaseButton::BaseButton() {
status.pressing_button=0;
set_focus_mode( FOCUS_ALL );
enabled_focus_mode = FOCUS_ALL;
- group=NULL;
+
+
+ if (button_group.is_valid()) {
+ button_group->buttons.erase(this);
+ }
}
@@ -525,4 +574,30 @@ BaseButton::~BaseButton()
{
}
+void ButtonGroup::get_buttons(List<BaseButton*> *r_buttons) {
+ for (Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) {
+ r_buttons->push_back(E->get());
+ }
+}
+
+BaseButton* ButtonGroup::get_pressed_button() {
+
+ for (Set<BaseButton*>::Element *E=buttons.front();E;E=E->next()) {
+ if (E->get()->is_pressed())
+ return E->get();
+ }
+
+ return NULL;
+
+}
+
+void ButtonGroup::_bind_methods() {
+
+ ClassDB::bind_method(_MD("get_pressed_button:BaseButton"),&ButtonGroup::get_pressed_button);
+}
+
+ButtonGroup::ButtonGroup() {
+
+ set_local_to_scene(true);
+}
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index ed39b34aa8..898c19e811 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -59,9 +59,11 @@ class BaseButton : public Control {
} status;
- ButtonGroup *group;
+ Ref<ButtonGroup> button_group;
+ void _unpress_group();
+
protected:
@@ -109,11 +111,29 @@ public:
virtual String get_tooltip(const Point2& p_pos) const;
+ void set_button_group(const Ref<ButtonGroup>& p_group);
+ Ref<ButtonGroup> get_button_group() const;
+
BaseButton();
~BaseButton();
};
-VARIANT_ENUM_CAST( BaseButton::DrawMode );
+VARIANT_ENUM_CAST( BaseButton::DrawMode )
+
+
+class ButtonGroup : public Resource {
+
+ GDCLASS(ButtonGroup,Resource)
+friend class BaseButton;
+ Set<BaseButton*> buttons;
+protected:
+ static void _bind_methods();
+public:
+
+ BaseButton* get_pressed_button();
+ void get_buttons(List<BaseButton*> *r_buttons);
+ ButtonGroup();
+};
#endif
diff --git a/scene/gui/button.h b/scene/gui/button.h
index 710581a556..2fd3a0cace 100644
--- a/scene/gui/button.h
+++ b/scene/gui/button.h
@@ -33,6 +33,9 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
+
+
+
class Button : public BaseButton {
GDCLASS( Button, BaseButton );
diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp
index 8586296ba6..01a3f633c3 100644
--- a/scene/gui/button_group.cpp
+++ b/scene/gui/button_group.cpp
@@ -27,6 +27,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "button_group.h"
+
+#if 0
#include "base_button.h"
void ButtonGroup::_add_button(BaseButton *p_button) {
@@ -162,3 +164,4 @@ void ButtonGroup::_bind_methods() {
ButtonGroup::ButtonGroup() : BoxContainer(true)
{
}
+#endif
diff --git a/scene/gui/button_group.h b/scene/gui/button_group.h
index e3380295e7..38acd06984 100644
--- a/scene/gui/button_group.h
+++ b/scene/gui/button_group.h
@@ -31,7 +31,7 @@
#include "scene/gui/box_container.h"
-
+#if 0
class BaseButton;
class ButtonGroup : public BoxContainer {
@@ -63,4 +63,5 @@ public:
ButtonGroup();
};
+#endif
#endif // BUTTON_GROUP_H
diff --git a/scene/gui/check_box.cpp b/scene/gui/check_box.cpp
index 901386eb45..c9803bc654 100644
--- a/scene/gui/check_box.cpp
+++ b/scene/gui/check_box.cpp
@@ -56,14 +56,8 @@ void CheckBox::_notification(int p_what) {
bool CheckBox::is_radio()
{
- Node* parent = this;
- do {
- parent = parent->get_parent();
- if (parent->cast_to<ButtonGroup>())
- break;
- } while (parent);
- return (parent != 0);
+ return get_button_group().is_valid();
}
CheckBox::CheckBox(const String &p_text):
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 8d8e41812b..02d5d5ce30 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -51,6 +51,49 @@
#include "globals.h"
+void ViewportTexture::setup_local_to_scene() {
+
+ if (vp) {
+ vp->viewport_textures.erase(this);
+ }
+
+ vp=NULL;
+
+ Node *local_scene = get_local_scene();
+ if (!local_scene) {
+ return;
+ }
+
+ Node *vpn = local_scene->get_node(path);
+ ERR_EXPLAIN("ViewportTexture: Path to node is invalid");
+ ERR_FAIL_COND(!vpn);
+
+ vp = vpn->cast_to<Viewport>();
+
+ ERR_EXPLAIN("ViewportTexture: Path to node does not point to a viewport");
+ ERR_FAIL_COND(!vp);
+
+ vp->viewport_textures.insert(this);
+}
+
+void ViewportTexture::set_viewport_path_in_scene(const NodePath& p_path) {
+
+ if (path==p_path)
+ return;
+
+ path=p_path;
+
+ if (get_local_scene()) {
+ setup_local_to_scene();
+ }
+
+}
+
+NodePath ViewportTexture::get_viewport_path_in_scene() const {
+
+ return path;
+}
+
int ViewportTexture::get_width() const {
ERR_FAIL_COND_V(!vp,0);
@@ -82,24 +125,40 @@ void ViewportTexture::set_flags(uint32_t p_flags){
if (!vp)
return;
- if (p_flags&FLAG_FILTER)
- flags=FLAG_FILTER;
- else
- flags=0;
-
- VS::get_singleton()->texture_set_flags(vp->texture_rid,flags);
+ vp->texture_flags=p_flags;
+ VS::get_singleton()->texture_set_flags(vp->texture_rid,p_flags);
}
uint32_t ViewportTexture::get_flags() const{
- return flags;
+ if (!vp)
+ return 0;
+
+ return vp->texture_flags;
+}
+
+void ViewportTexture::_bind_methods() {
+
+ ClassDB::bind_method(_MD("set_viewport_path_in_scene","path"),&ViewportTexture::set_viewport_path_in_scene);
+ ClassDB::bind_method(_MD("get_viewport_path_in_scene"),&ViewportTexture::get_viewport_path_in_scene);
+
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH,"viewport_path"),_SCS("set_viewport_path_in_scene"),_SCS("get_viewport_path_in_scene"));
+
+}
+
+ViewportTexture::ViewportTexture(){
+
+ vp=NULL;
+ set_local_to_scene(true);
+
}
-ViewportTexture::ViewportTexture(Viewport *p_vp){
+ViewportTexture::~ViewportTexture(){
- vp=p_vp;
- flags=0;
+ if (vp) {
+ vp->viewport_textures.erase(this);
+ }
}
/////////////////////////////////////
@@ -1256,7 +1315,11 @@ Image Viewport::get_screen_capture() const {
Ref<ViewportTexture> Viewport::get_texture() const {
- return texture;
+ Ref<ViewportTexture> vt;
+ vt.instance();
+ vt->vp=const_cast<Viewport*>(this);
+
+ return vt;
}
void Viewport::set_vflip(bool p_enable) {
@@ -2788,6 +2851,7 @@ Viewport::Viewport() {
viewport = VisualServer::get_singleton()->viewport_create();
texture_rid=VisualServer::get_singleton()->viewport_get_texture(viewport);
+ texture_flags=0;
internal_listener = SpatialSoundServer::get_singleton()->listener_create();
audio_listener=false;
internal_listener_2d = SpatialSound2DServer::get_singleton()->listener_create();
@@ -2805,7 +2869,6 @@ Viewport::Viewport() {
clear_on_new_frame=true;
//clear=true;
update_mode=UPDATE_WHEN_VISIBLE;
- texture = Ref<ViewportTexture>( memnew( ViewportTexture(this) ) );
physics_object_picking=false;
physics_object_capture=0;
@@ -2853,11 +2916,14 @@ Viewport::Viewport() {
Viewport::~Viewport() {
+ //erase itself from viewport textures
+ for(Set<ViewportTexture*>::Element *E=viewport_textures.front();E;E=E->next()) {
+ E->get()->vp=NULL;
+ }
VisualServer::get_singleton()->free( viewport );
SpatialSoundServer::get_singleton()->free(internal_listener);
SpatialSound2DServer::get_singleton()->free(internal_listener_2d);
- if (texture.is_valid())
- texture->vp=NULL; //so if used, will crash
+
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 702c9f792f..5feeae6237 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -52,13 +52,20 @@ class ViewportTexture : public Texture {
GDCLASS( ViewportTexture, Texture );
- int flags;
-friend class Viewport;
- Viewport *vp;
+ NodePath path;
+friend class Viewport;
+ Viewport* vp;
+protected:
+ static void _bind_methods();
public:
+ void set_viewport_path_in_scene(const NodePath& p_path);
+ NodePath get_viewport_path_in_scene() const;
+
+ virtual void setup_local_to_scene();
+
virtual int get_width() const;
virtual int get_height() const;
@@ -70,7 +77,8 @@ public:
virtual void set_flags(uint32_t p_flags);
virtual uint32_t get_flags() const;
- ViewportTexture(Viewport *p_vp=NULL);
+ ViewportTexture();
+ ~ViewportTexture();
};
@@ -191,7 +199,7 @@ friend class ViewportTexture;
bool disable_3d;
UpdateMode update_mode;
RID texture_rid;
- Ref<ViewportTexture> texture;
+ uint32_t texture_flags;
int shadow_atlas_size;
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
@@ -199,6 +207,8 @@ friend class ViewportTexture;
MSAA msaa;
bool hdr;
+ Set<ViewportTexture*> viewport_textures;
+
struct GUI {
// info used when this is a window
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index c3b98af811..b0161f6898 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -42,7 +42,7 @@ bool SceneState::can_instance() const {
}
-Node *SceneState::instance(bool p_gen_edit_state) const {
+Node *SceneState::instance(GenEditState p_edit_state) const {
// nodes where instancing failed (because something is missing)
List<Node*> stray_instances;
@@ -76,7 +76,9 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
Node **ret_nodes=(Node**)alloca( sizeof(Node*)*nc );
- bool gen_node_path_cache=p_gen_edit_state && node_path_cache.empty();
+ bool gen_node_path_cache=p_edit_state!=GEN_EDIT_STATE_DISABLED && node_path_cache.empty();
+
+ Map<Ref<Resource>,Ref<Resource> > resources_local_to_scene;
for(int i=0;i<nc;i++) {
@@ -105,9 +107,9 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
//print_line("scene inherit");
Ref<PackedScene> sdata = props[ base_scene_idx ];
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
- node = sdata->instance(p_gen_edit_state);
+ node = sdata->instance(p_edit_state==GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE); //only main gets main edit state
ERR_FAIL_COND_V(!node,NULL);
- if (p_gen_edit_state) {
+ if (p_edit_state!=GEN_EDIT_STATE_DISABLED) {
node->set_scene_inherited_state(sdata->get_state());
}
@@ -121,7 +123,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
Ref<PackedScene> sdata = ResourceLoader::load(path,"PackedScene");
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
- node = sdata->instance(p_gen_edit_state);
+ node = sdata->instance(p_edit_state==GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE);
ERR_FAIL_COND_V(!node,NULL);
} else {
InstancePlaceholder *ip = memnew( InstancePlaceholder );
@@ -132,7 +134,7 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
} else {
Ref<PackedScene> sdata = props[ n.instance&FLAG_MASK ];
ERR_FAIL_COND_V( !sdata.is_valid(), NULL);
- node = sdata->instance(p_gen_edit_state);
+ node = sdata->instance(p_edit_state==GEN_EDIT_STATE_DISABLED ? PackedScene::GEN_EDIT_STATE_DISABLED : PackedScene::GEN_EDIT_STATE_INSTANCE);
ERR_FAIL_COND_V(!node,NULL);
}
@@ -166,8 +168,8 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
} else if (ret_nodes[n.parent]->cast_to<Node2D>()) {
obj = memnew( Node2D );
}
-
}
+
if (!obj) {
obj = memnew( Node );
}
@@ -212,7 +214,43 @@ Node *SceneState::instance(bool p_gen_edit_state) const {
}
} else {
- node->set(snames[ nprops[j].name ],props[ nprops[j].value ],&valid);
+ Variant value = props[ nprops[j].value ];
+
+ if (value.get_type()==Variant::OBJECT) {
+ //handle resources that are local to scene by duplicating them if needed
+ Ref<Resource> res = value;
+ if (res.is_valid()) {
+ if (res->is_local_to_scene()) {
+
+ Map<Ref<Resource>,Ref<Resource> >::Element *E=resources_local_to_scene.find(res);
+
+ if (E) {
+ value=E->get();
+ } else {
+
+ Node *base = i==0?node:ret_nodes[0];
+
+ if (p_edit_state==GEN_EDIT_STATE_MAIN) {
+
+ res->local_scene=base;
+ resources_local_to_scene[res]=res;
+
+ } else {
+ Node *base = i==0?node:ret_nodes[0];
+ Ref<Resource> local_dupe = res->duplicate_for_local_scene(base,resources_local_to_scene);
+ resources_local_to_scene[res]=local_dupe;
+ res=local_dupe;
+ value=local_dupe;
+ }
+
+ res->setup_local_to_scene();
+
+ }
+ //must make a copy, because this res is local to scene
+ }
+ }
+ }
+ node->set(snames[ nprops[j].name ],value,&valid);
}
}
}
@@ -1693,6 +1731,10 @@ void SceneState::_bind_methods() {
ClassDB::bind_method(_MD("get_connection_method","idx"),&SceneState::get_connection_method);
ClassDB::bind_method(_MD("get_connection_flags","idx"),&SceneState::get_connection_flags);
ClassDB::bind_method(_MD("get_connection_binds","idx"),&SceneState::get_connection_binds);
+
+ BIND_CONSTANT( GEN_EDIT_STATE_DISABLED );
+ BIND_CONSTANT( GEN_EDIT_STATE_INSTANCE );
+ BIND_CONSTANT( GEN_EDIT_STATE_MAIN );
}
SceneState::SceneState() {
@@ -1732,7 +1774,7 @@ bool PackedScene::can_instance() const {
return state->can_instance();
}
-Node *PackedScene::instance(bool p_gen_edit_state) const {
+Node *PackedScene::instance(GenEditState p_edit_state) const {
#ifndef TOOLS_ENABLED
if (p_gen_edit_state) {
@@ -1741,11 +1783,11 @@ Node *PackedScene::instance(bool p_gen_edit_state) const {
}
#endif
- Node *s = state->instance(p_gen_edit_state);
+ Node *s = state->instance((SceneState::GenEditState)p_edit_state);
if (!s)
return NULL;
- if (p_gen_edit_state) {
+ if (p_edit_state!=GEN_EDIT_STATE_DISABLED) {
s->set_scene_instance_state(state);
}
@@ -1792,7 +1834,7 @@ void PackedScene::set_path(const String& p_path,bool p_take_over) {
void PackedScene::_bind_methods() {
ClassDB::bind_method(_MD("pack","path:Node"),&PackedScene::pack);
- ClassDB::bind_method(_MD("instance:Node","gen_edit_state"),&PackedScene::instance,DEFVAL(false));
+ ClassDB::bind_method(_MD("instance:Node","edit_state"),&PackedScene::instance,DEFVAL(false));
ClassDB::bind_method(_MD("can_instance"),&PackedScene::can_instance);
ClassDB::bind_method(_MD("_set_bundled_scene"),&PackedScene::_set_bundled_scene);
ClassDB::bind_method(_MD("_get_bundled_scene"),&PackedScene::_get_bundled_scene);
@@ -1800,6 +1842,10 @@ void PackedScene::_bind_methods() {
ADD_PROPERTY( PropertyInfo(Variant::DICTIONARY,"_bundled"),_SCS("_set_bundled_scene"),_SCS("_get_bundled_scene"));
+ BIND_CONSTANT( GEN_EDIT_STATE_DISABLED );
+ BIND_CONSTANT( GEN_EDIT_STATE_INSTANCE );
+ BIND_CONSTANT( GEN_EDIT_STATE_MAIN );
+
}
PackedScene::PackedScene() {
diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h
index fd4ed106df..381b356b1e 100644
--- a/scene/resources/packed_scene.h
+++ b/scene/resources/packed_scene.h
@@ -117,6 +117,12 @@ public:
FLAG_MASK=(1<<24)-1,
};
+ enum GenEditState {
+ GEN_EDIT_STATE_DISABLED,
+ GEN_EDIT_STATE_INSTANCE,
+ GEN_EDIT_STATE_MAIN,
+ };
+
static void set_disable_placeholders(bool p_disable);
int find_node_by_path(const NodePath& p_node) const;
@@ -136,7 +142,7 @@ public:
void clear();
bool can_instance() const;
- Node *instance(bool p_gen_edit_state=false) const;
+ Node *instance(GenEditState p_edit_state) const;
//unbuild API
@@ -187,6 +193,8 @@ public:
SceneState();
};
+VARIANT_ENUM_CAST(SceneState::GenEditState)
+
class PackedScene : public Resource {
GDCLASS(PackedScene, Resource );
@@ -203,13 +211,18 @@ protected:
static void _bind_methods();
public:
+ enum GenEditState {
+ GEN_EDIT_STATE_DISABLED,
+ GEN_EDIT_STATE_INSTANCE,
+ GEN_EDIT_STATE_MAIN,
+ };
Error pack(Node *p_scene);
void clear();
bool can_instance() const;
- Node *instance(bool p_gen_edit_state=false) const;
+ Node *instance(GenEditState p_edit_state=GEN_EDIT_STATE_DISABLED) const;
void recreate_state();
void replace_state(Ref<SceneState> p_by);
@@ -225,4 +238,6 @@ public:
};
+VARIANT_ENUM_CAST(PackedScene::GenEditState)
+
#endif // SCENE_PRELOADER_H
diff --git a/tools/editor/editor_data.cpp b/tools/editor/editor_data.cpp
index 11ba30f4f0..f27fe79a85 100644
--- a/tools/editor/editor_data.cpp
+++ b/tools/editor/editor_data.cpp
@@ -584,7 +584,7 @@ bool EditorData::check_and_update_scene(int p_idx) {
Error err = pscene->pack(edited_scene[p_idx].root);
ERR_FAIL_COND_V(err!=OK,false);
ep.step(TTR("Updating scene.."),1);
- Node *new_scene = pscene->instance(true);
+ Node *new_scene = pscene->instance(PackedScene::GEN_EDIT_STATE_MAIN);
ERR_FAIL_COND_V(!new_scene,false);
//transfer selection
diff --git a/tools/editor/editor_node.cpp b/tools/editor/editor_node.cpp
index 5eb5f42001..2306f98349 100644
--- a/tools/editor/editor_node.cpp
+++ b/tools/editor/editor_node.cpp
@@ -3745,7 +3745,7 @@ Error EditorNode::load_scene(const String& p_scene, bool p_ignore_broken_deps,bo
sdata->set_path(lpath,true); //take over path
}
- Node*new_scene=sdata->instance(true);
+ Node*new_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_MAIN);
if (!new_scene) {
@@ -5365,8 +5365,15 @@ void EditorNode::_bind_methods() {
}
+static Node* _resource_get_edited_scene() {
+
+ return EditorNode::get_singleton()->get_edited_scene();
+}
+
EditorNode::EditorNode() {
+ Resource::_get_local_scene_func=_resource_get_edited_scene;
+
VisualServer::get_singleton()->textures_keep_original(true);
EditorHelp::generate_doc(); //before any editor classes are crated
diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
index 16bc334cce..96e49a0a7f 100644
--- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -664,7 +664,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin*
mode_hb->add_child(vbcg);
mode_hb->add_constant_override("separation",15);
- ButtonGroup *bg = memnew( ButtonGroup );
+ VBoxContainer *bg = memnew( VBoxContainer );
vbcg->add_margin_child("Import Mode",bg);
for(int i=0;i<EditorTextureImportPlugin::MODE_MAX;i++) {
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.cpp b/tools/editor/plugins/canvas_item_editor_plugin.cpp
index 7fecd60484..6839326886 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/tools/editor/plugins/canvas_item_editor_plugin.cpp
@@ -3671,7 +3671,10 @@ void CanvasItemEditorViewport::_on_select_type(Object* selected) {
}
void CanvasItemEditorViewport::_on_change_type() {
- CheckBox* check=btn_group->get_pressed_button()->cast_to<CheckBox>();
+ if (!button_group->get_pressed_button())
+ return;
+
+ CheckBox* check=button_group->get_pressed_button()->cast_to<CheckBox>();
default_type=check->get_text();
_perform_drop_data();
selector->hide();
@@ -3798,7 +3801,7 @@ bool CanvasItemEditorViewport::_create_instance(Node* parent, String& path, cons
return false;
}
- Node* instanced_scene=sdata->instance(true);
+ Node* instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) { // error on instancing
return false;
}
@@ -3899,7 +3902,7 @@ bool CanvasItemEditorViewport::can_drop_data(const Point2& p_point,const Variant
String type=res->get_class();
if (type=="PackedScene") {
Ref<PackedScene> sdata=ResourceLoader::load(files[i]);
- Node* instanced_scene=sdata->instance(true);
+ Node* instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
continue;
}
@@ -3957,7 +3960,8 @@ void CanvasItemEditorViewport::drop_data(const Point2& p_point,const Variant& p_
if (is_alt) {
List<BaseButton*> btn_list;
- btn_group->get_button_list(&btn_list);
+ button_group->get_buttons(&btn_list);
+
for (int i=0;i<btn_list.size();i++) {
CheckBox* check=btn_list[i]->cast_to<CheckBox>();
check->set_pressed(check->get_text()==default_type);
@@ -4016,7 +4020,9 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
selector_label->set_custom_minimum_size(Size2(0,30)*EDSCALE);
vbc->add_child(selector_label);
- btn_group=memnew( ButtonGroup );
+ button_group.instance();
+
+ btn_group=memnew( VBoxContainer );
btn_group->set_h_size_flags(0);
btn_group->connect("button_selected", this, "_on_select_type");
@@ -4024,6 +4030,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
CheckBox* check=memnew(CheckBox);
check->set_text(types[i]);
btn_group->add_child(check);
+ check->set_button_group(button_group);
}
vbc->add_child(btn_group);
diff --git a/tools/editor/plugins/canvas_item_editor_plugin.h b/tools/editor/plugins/canvas_item_editor_plugin.h
index f74df9d6e0..ee36554477 100644
--- a/tools/editor/plugins/canvas_item_editor_plugin.h
+++ b/tools/editor/plugins/canvas_item_editor_plugin.h
@@ -473,7 +473,8 @@ class CanvasItemEditorViewport : public VBoxContainer {
Label* selector_label;
Label* label;
Label* label_desc;
- ButtonGroup* btn_group;
+ VBoxContainer* btn_group;
+ Ref<ButtonGroup> button_group;
void _on_mouse_exit();
void _on_select_type(Object* selected);
diff --git a/tools/editor/plugins/theme_editor_plugin.cpp b/tools/editor/plugins/theme_editor_plugin.cpp
index ad0968178b..a700ddce7a 100644
--- a/tools/editor/plugins/theme_editor_plugin.cpp
+++ b/tools/editor/plugins/theme_editor_plugin.cpp
@@ -711,7 +711,7 @@ ThemeEditor::ThemeEditor() {
first_vb->add_child(cbx );
- ButtonGroup *bg = memnew( ButtonGroup );
+ VBoxContainer *bg = memnew( VBoxContainer );
bg->set_v_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *gbvb = memnew( VBoxContainer );
gbvb->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/tools/editor/property_editor.cpp b/tools/editor/property_editor.cpp
index 1a2749cd95..4c69412b3b 100644
--- a/tools/editor/property_editor.cpp
+++ b/tools/editor/property_editor.cpp
@@ -226,8 +226,19 @@ void CustomPropertyEditor::_menu_option(int p_which) {
ERR_FAIL_COND( inheritors_array.empty() );
+
+
String intype=inheritors_array[p_which-TYPE_BASE_ID];
+ if (intype=="ViewportTexture") {
+
+ scene_tree->set_title(TTR("Pick a Viewport"));
+ scene_tree->popup_centered_ratio();
+ picking_viewport=true;
+ return;
+
+ }
+
Object *obj = ClassDB::instance(intype);
ERR_BREAK( !obj );
Resource *res=obj->cast_to<Resource>();
@@ -1126,6 +1137,22 @@ void CustomPropertyEditor::_color_changed(const Color& p_color) {
void CustomPropertyEditor::_node_path_selected(NodePath p_path) {
+ if (picking_viewport) {
+
+ Node* to_node=get_node(p_path);
+ if (!to_node->cast_to<Viewport>()) {
+ EditorNode::get_singleton()->show_warning("Selected node is not a Viewport!");
+ return;
+ }
+
+ Ref<ViewportTexture> vt;
+ vt.instance();
+ vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node));
+ vt->setup_local_to_scene();
+ v=vt;
+ emit_signal("variant_changed");
+ return;
+ }
if (hint==PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE && hint_text!=String()) {
@@ -1262,7 +1289,8 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
if (p_which==0) {
-
+ picking_viewport=false;
+ scene_tree->set_title(TTR("Pick a Node"));
scene_tree->popup_centered_ratio();
} else if (p_which==1) {
@@ -3807,6 +3835,8 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
undo_redo->create_action(TTR("Set")+" "+p_name,UndoRedo::MERGE_ENDS);
undo_redo->add_do_property(obj,p_name,p_value);
undo_redo->add_undo_property(obj,p_name,obj->get(p_name));
+
+
undo_redo->add_do_method(this,"_changed_callback",obj,p_name);
undo_redo->add_undo_method(this,"_changed_callback",obj,p_name);
@@ -3816,6 +3846,17 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
undo_redo->add_do_method(r,"set_edited",true);
undo_redo->add_undo_method(r,"set_edited",false);
}
+
+ if (String(p_name)=="resource_local_to_scene") {
+ bool prev = obj->get(p_name);
+ bool next = p_value;
+ if (next) {
+ undo_redo->add_do_method(this,"setup_local_to_scene");
+ }
+ if (prev) {
+ undo_redo->add_undo_method(this,"setup_local_to_scene");
+ }
+ }
}
undo_redo->add_do_method(this,"emit_signal",_prop_edited,p_name);
undo_redo->add_undo_method(this,"emit_signal",_prop_edited,p_name);
diff --git a/tools/editor/property_editor.h b/tools/editor/property_editor.h
index df180cab18..af7d01f935 100644
--- a/tools/editor/property_editor.h
+++ b/tools/editor/property_editor.h
@@ -99,6 +99,7 @@ class CustomPropertyEditor : public Popup {
ColorPicker *color_picker;
TextEdit *text_edit;
bool read_only;
+ bool picking_viewport;
CheckBox *checks20[20];
SpinBox *spinbox;
HSlider *slider;
diff --git a/tools/editor/scene_tree_dock.cpp b/tools/editor/scene_tree_dock.cpp
index 70195862de..c171c49c7b 100644
--- a/tools/editor/scene_tree_dock.cpp
+++ b/tools/editor/scene_tree_dock.cpp
@@ -174,7 +174,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String>& p_files,Node*
}
- Node*instanced_scene=sdata->instance(true);
+ Node*instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
current_option=-1;
//accept->get_cancel()->hide();
@@ -250,7 +250,7 @@ void SceneTreeDock::_replace_with_branch_scene(const String& p_file,Node* base)
return;
}
- Node *instanced_scene=sdata->instance(true);
+ Node *instanced_scene=sdata->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
if (!instanced_scene) {
accept->get_ok()->set_text(TTR("Ugh"));
accept->set_text(vformat(TTR("Error instancing scene from %s"),p_file));
@@ -744,7 +744,7 @@ Node *SceneTreeDock::_duplicate(Node *p_node, Map<Node*,Node*> &duplimap) {
Ref<PackedScene> sd = ResourceLoader::load( p_node->get_filename() );
ERR_FAIL_COND_V(!sd.is_valid(),NULL);
- node = sd->instance(true);
+ node = sd->instance(PackedScene::GEN_EDIT_STATE_INSTANCE);
ERR_FAIL_COND_V(!node,NULL);
//node->generate_instance_state();
} else {