diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/gui/base_button.cpp | 107 | ||||
-rw-r--r-- | scene/gui/base_button.h | 24 | ||||
-rw-r--r-- | scene/gui/button.h | 3 | ||||
-rw-r--r-- | scene/gui/button_group.cpp | 3 | ||||
-rw-r--r-- | scene/gui/button_group.h | 3 | ||||
-rw-r--r-- | scene/gui/check_box.cpp | 8 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 94 | ||||
-rw-r--r-- | scene/main/viewport.h | 20 | ||||
-rw-r--r-- | scene/resources/packed_scene.cpp | 70 | ||||
-rw-r--r-- | scene/resources/packed_scene.h | 19 |
10 files changed, 292 insertions, 59 deletions
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 |