diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-04-10 00:18:27 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-04-10 00:18:27 -0300 |
commit | 7ea3e8267afaf626256c84a9a3dc61e2954fc6a2 (patch) | |
tree | 0aa7588918b814d1781fc94e8b518c7095a0bab7 /scene | |
parent | b4969373b3475799d6b24cdffeda4659c37f0b8a (diff) |
-Fixed a few bugs in Viewport
-Made a few demos using Viewport to show it's true power!
-Fixed some start-up error messages.
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/canvas_item.cpp | 35 | ||||
-rw-r--r-- | scene/2d/canvas_item.h | 4 | ||||
-rw-r--r-- | scene/2d/sprite.cpp | 201 | ||||
-rw-r--r-- | scene/2d/sprite.h | 40 | ||||
-rw-r--r-- | scene/3d/quad.h | 1 | ||||
-rw-r--r-- | scene/gui/control.cpp | 4 | ||||
-rw-r--r-- | scene/gui/file_dialog.cpp | 54 | ||||
-rw-r--r-- | scene/gui/file_dialog.h | 1 | ||||
-rw-r--r-- | scene/gui/menu_button.cpp | 2 | ||||
-rw-r--r-- | scene/main/node.cpp | 67 | ||||
-rw-r--r-- | scene/main/node.h | 9 | ||||
-rw-r--r-- | scene/main/scene_main_loop.cpp | 19 | ||||
-rw-r--r-- | scene/main/scene_main_loop.h | 2 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 137 | ||||
-rw-r--r-- | scene/main/viewport.h | 19 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 1 | ||||
-rw-r--r-- | scene/resources/default_theme/default_theme.cpp | 2 |
17 files changed, 552 insertions, 46 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 2e10ae2edb..8eb5c9dfc8 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -255,7 +255,7 @@ void CanvasItem::_enter_canvas() { if ((!get_parent() || !get_parent()->cast_to<CanvasItem>()) || toplevel) { Node *n = this; - viewport=NULL; + Viewport *viewport=NULL; canvas_layer=NULL; while(n) { @@ -288,15 +288,10 @@ void CanvasItem::_enter_canvas() { } else { CanvasItem *parent = get_parent_item(); - viewport=parent->viewport; VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent->get_canvas_item()); parent->_queue_sort_children(); } - if (!viewport) { - - print_line("no viewport wtf!"); - } pending_update=false; update(); @@ -308,7 +303,6 @@ void CanvasItem::_exit_canvas() { notification(NOTIFICATION_EXIT_CANVAS,true); //reverse the notification VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,RID()); - viewport=NULL; canvas_layer=NULL; group=""; @@ -655,7 +649,7 @@ void CanvasItem::_notify_transform(CanvasItem *p_node) { Rect2 CanvasItem::get_viewport_rect() const { ERR_FAIL_COND_V(!is_inside_scene(),Rect2()); - return viewport->get_visible_rect(); + return get_viewport()->get_visible_rect(); } RID CanvasItem::get_canvas() const { @@ -665,7 +659,7 @@ RID CanvasItem::get_canvas() const { if (canvas_layer) return canvas_layer->get_world_2d()->get_canvas(); else - return viewport->find_world_2d()->get_canvas(); + return get_viewport()->find_world_2d()->get_canvas(); } @@ -680,11 +674,6 @@ CanvasItem *CanvasItem::get_toplevel() const { return ci; } -Viewport *CanvasItem::get_viewport() const { - - return viewport; -} - Ref<World2D> CanvasItem::get_world_2d() const { @@ -694,8 +683,8 @@ Ref<World2D> CanvasItem::get_world_2d() const { if (tl->canvas_layer) { return tl->canvas_layer->get_world_2d(); - } else if (tl->viewport) { - return tl->viewport->find_world_2d(); + } else if (tl->get_viewport()) { + return tl->get_viewport()->find_world_2d(); } else { return Ref<World2D>(); } @@ -705,7 +694,7 @@ Ref<World2D> CanvasItem::get_world_2d() const { RID CanvasItem::get_viewport_rid() const { ERR_FAIL_COND_V(!is_inside_scene(),RID()); - return viewport->get_viewport(); + return get_viewport()->get_viewport(); } void CanvasItem::set_block_transform_notify(bool p_enable) { @@ -795,7 +784,7 @@ void CanvasItem::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_viewport_rect"),&CanvasItem::get_viewport_rect); ObjectTypeDB::bind_method(_MD("get_canvas"),&CanvasItem::get_canvas); ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d); - ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport); + //ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport); BIND_VMETHOD(MethodInfo("_draw")); @@ -838,14 +827,14 @@ Matrix32 CanvasItem::get_viewport_transform() const { if (canvas_layer) { - if (viewport) { - return viewport->get_final_transform() * canvas_layer->get_transform(); + if (get_viewport()) { + return get_viewport()->get_final_transform() * canvas_layer->get_transform(); } else { return canvas_layer->get_transform(); } - } else if (viewport) { - return viewport->get_final_transform() * viewport->get_canvas_transform(); + } else if (get_viewport()) { + return get_viewport()->get_final_transform() * get_viewport()->get_canvas_transform(); } return Matrix32(); @@ -868,7 +857,7 @@ CanvasItem::CanvasItem() : xform_change(this) { drawing=false; behind=false; block_transform_notify=false; - viewport=NULL; +// viewport=NULL; canvas_layer=NULL; global_invalid=true; diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 5489e105d9..397b206677 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -59,7 +59,7 @@ private: RID canvas_item; String group; - Viewport *viewport; + CanvasLayer *canvas_layer; float opacity; @@ -200,7 +200,7 @@ public: RID get_viewport_rid() const; RID get_canvas() const; Ref<World2D> get_world_2d() const; - Viewport *get_viewport() const; + CanvasItem(); diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp index ad9a76ee35..7d033ed87f 100644 --- a/scene/2d/sprite.cpp +++ b/scene/2d/sprite.cpp @@ -29,6 +29,8 @@ #include "sprite.h" #include "core/core_string_names.h" #include "scene/scene_string_names.h" +#include "scene/main/viewport.h" + void Sprite::edit_set_pivot(const Point2& p_pivot) { set_offset(p_pivot); @@ -335,3 +337,202 @@ Sprite::Sprite() { } + + + + +//////////////////////////// VPSPRITE +/// +/// +/// + + +void ViewportSprite::edit_set_pivot(const Point2& p_pivot) { + + set_offset(p_pivot); +} + +Point2 ViewportSprite::edit_get_pivot() const { + + return get_offset(); +} +bool ViewportSprite::edit_has_pivot() const { + + return true; +} + +void ViewportSprite::_notification(int p_what) { + + switch(p_what) { + + case NOTIFICATION_ENTER_SCENE: { + + if (!viewport_path.is_empty()) { + + Node *n = get_node(viewport_path); + ERR_FAIL_COND(!n); + Viewport *vp=n->cast_to<Viewport>(); + ERR_FAIL_COND(!vp); + + Ref<RenderTargetTexture> rtt = vp->get_render_target_texture(); + texture=rtt; + texture->connect("changed",this,"update"); + item_rect_changed(); + } + } break; + case NOTIFICATION_EXIT_SCENE: { + + if (texture.is_valid()) { + + texture->disconnect("changed",this,"update"); + texture=Ref<Texture>(); + } + } break; + case NOTIFICATION_DRAW: { + + if (texture.is_null()) + return; + + RID ci = get_canvas_item(); + + /* + texture->draw(ci,Point2()); + break; + */ + + Size2i s; + Rect2i src_rect; + + s = texture->get_size(); + + src_rect.size=s; + + Point2i ofs=offset; + if (centered) + ofs-=s/2; + + Rect2i dst_rect(ofs,s); + texture->draw_rect_region(ci,dst_rect,src_rect,modulate); + + } break; + } +} + +void ViewportSprite::set_viewport_path(const NodePath& p_viewport) { + + viewport_path=p_viewport; + update(); + if (!is_inside_scene()) + return; + + if (texture.is_valid()) { + texture->disconnect("changed",this,"update"); + texture=Ref<Texture>(); + } + + if (viewport_path.is_empty()) + return; + + + Node *n = get_node(viewport_path); + ERR_FAIL_COND(!n); + Viewport *vp=n->cast_to<Viewport>(); + ERR_FAIL_COND(!vp); + + Ref<RenderTargetTexture> rtt = vp->get_render_target_texture(); + texture=rtt; + + if (texture.is_valid()) { + texture->connect("changed",this,"update"); + } + + item_rect_changed(); + +} + +NodePath ViewportSprite::get_viewport_path() const { + + return viewport_path; +} + +void ViewportSprite::set_centered(bool p_center) { + + centered=p_center; + update(); + item_rect_changed(); +} + +bool ViewportSprite::is_centered() const { + + return centered; +} + +void ViewportSprite::set_offset(const Point2& p_offset) { + + offset=p_offset; + update(); + item_rect_changed(); +} +Point2 ViewportSprite::get_offset() const { + + return offset; +} +void ViewportSprite::set_modulate(const Color& p_color) { + + modulate=p_color; + update(); +} + +Color ViewportSprite::get_modulate() const{ + + return modulate; +} + + +Rect2 ViewportSprite::get_item_rect() const { + + if (texture.is_null()) + return Rect2(0,0,1,1); + //if (texture.is_null()) + // return CanvasItem::get_item_rect(); + + Size2i s; + + s = texture->get_size(); + Point2i ofs=offset; + if (centered) + ofs-=s/2; + + if (s==Size2(0,0)) + s=Size2(1,1); + + return Rect2(ofs,s); +} + + +void ViewportSprite::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_viewport_path","path"),&ViewportSprite::set_viewport_path); + ObjectTypeDB::bind_method(_MD("get_viewport_path"),&ViewportSprite::get_viewport_path); + + ObjectTypeDB::bind_method(_MD("set_centered","centered"),&ViewportSprite::set_centered); + ObjectTypeDB::bind_method(_MD("is_centered"),&ViewportSprite::is_centered); + + ObjectTypeDB::bind_method(_MD("set_offset","offset"),&ViewportSprite::set_offset); + ObjectTypeDB::bind_method(_MD("get_offset"),&ViewportSprite::get_offset); + + ObjectTypeDB::bind_method(_MD("set_modulate","modulate"),&ViewportSprite::set_modulate); + ObjectTypeDB::bind_method(_MD("get_modulate"),&ViewportSprite::get_modulate); + + ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "viewport"), _SCS("set_viewport_path"),_SCS("get_viewport_path")); + ADD_PROPERTY( PropertyInfo( Variant::BOOL, "centered"), _SCS("set_centered"),_SCS("is_centered")); + ADD_PROPERTY( PropertyInfo( Variant::VECTOR2, "offset"), _SCS("set_offset"),_SCS("get_offset")); + ADD_PROPERTY( PropertyInfo( Variant::COLOR, "modulate"), _SCS("set_modulate"),_SCS("get_modulate")); + +} + +ViewportSprite::ViewportSprite() { + + centered=true; + modulate=Color(1,1,1,1); +} diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h index 42f737fa91..f26852fea6 100644 --- a/scene/2d/sprite.h +++ b/scene/2d/sprite.h @@ -105,4 +105,44 @@ public: Sprite(); }; +class ViewportSprite : public Node2D { + + OBJ_TYPE( ViewportSprite, Node2D ); + + Ref<Texture> texture; + NodePath viewport_path; + + bool centered; + Point2 offset; + Color modulate; + +protected: + + void _notification(int p_what); + + static void _bind_methods();; + +public: + + virtual void edit_set_pivot(const Point2& p_pivot); + virtual Point2 edit_get_pivot() const; + virtual bool edit_has_pivot() const; + + void set_viewport_path(const NodePath& p_viewport); + NodePath get_viewport_path() const; + + void set_centered(bool p_center); + bool is_centered() const; + + void set_offset(const Point2& p_offset); + Point2 get_offset() const; + + void set_modulate(const Color& p_color); + Color get_modulate() const; + + virtual Rect2 get_item_rect() const; + + ViewportSprite(); +}; + #endif // SPRITE_H diff --git a/scene/3d/quad.h b/scene/3d/quad.h index 7d1b4f5dc4..4870b988f2 100644 --- a/scene/3d/quad.h +++ b/scene/3d/quad.h @@ -73,4 +73,5 @@ public: Quad(); }; + #endif // QUAD_H diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 83c0397554..9e0faac716 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -346,7 +346,7 @@ void Control::_notification(int p_notification) { if (data.window==this) { window = memnew( Window ); - add_to_group("_gui_input"); + add_to_group("_vp_gui_input"+itos(get_viewport()->get_instance_ID())); add_to_group("windows"); window->tooltip_timer = memnew( Timer ); @@ -401,7 +401,7 @@ void Control::_notification(int p_notification) { if (window) { - remove_from_group("_gui_input"); + remove_from_group("_vp_gui_input"+itos(get_viewport()->get_instance_ID())); remove_from_group("windows"); if (window->tooltip_timer) memdelete(window->tooltip_timer); diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index c4226e0f23..a7ff1431bd 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -156,11 +156,61 @@ void FileDialog::_action_pressed() { if (mode==MODE_SAVE_FILE) { + String ext = f.extension(); + bool valid=false; + + if (filter->get_selected()==filter->get_item_count()-1) { + valid=true; //match none + } else if (filters.size()>1 && filter->get_selected()==0) { + // match all filters + for (int i=0;i<filters.size();i++) { + + String flt=filters[i].get_slice(";",0); + for (int j=0;j<flt.get_slice_count(",");j++) { + + String str = flt.get_slice(",",j).strip_edges(); + if (f.match(str)) { + valid=true; + break; + } + } + if (valid) + break; + } + } else { + int idx=filter->get_selected(); + if (filters.size()>1) + idx--; + if (idx>=0 && idx<filters.size()) { + + String flt=filters[idx].get_slice(";",0); + for (int j=0;j<flt.get_slice_count(",");j++) { + + String str = (flt.get_slice(",",j).strip_edges()); + if (f.match(str)) { + valid=true; + break; + } + } + } else { + valid=true; + } + } + + + if (!valid) { + + exterr->popup_centered_minsize(Size2(250,80)); + return; + + } + if (dir_access->file_exists(f)) { confirm_save->set_text("File Exists, Overwrite?"); confirm_save->popup_centered(Size2(200,80)); } else { + emit_signal("file_selected",f); hide(); } @@ -682,6 +732,10 @@ FileDialog::FileDialog() { mkdirerr->set_text("Could not create folder."); add_child(mkdirerr); + exterr = memnew( AcceptDialog ); + exterr->set_text("Must use a valid extension."); + add_child(exterr); + //update_file_list(); update_filters(); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 6f274de52a..bda1797696 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -82,6 +82,7 @@ private: Tree *tree; LineEdit *file; AcceptDialog *mkdirerr; + AcceptDialog *exterr; OptionButton *filter; DirAccess *dir_access; ConfirmationDialog *confirm_save; diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp index 4d1609bef9..7353744d07 100644 --- a/scene/gui/menu_button.cpp +++ b/scene/gui/menu_button.cpp @@ -141,7 +141,7 @@ MenuButton::MenuButton() { popup->hide(); add_child(popup); popup->set_as_toplevel(true); - add_to_group("unhandled_key_input"); + set_process_unhandled_key_input(true); set_click_on_press(true); } diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 9b592a77d5..d4f043c538 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -33,6 +33,7 @@ #include "scene/scene_string_names.h" #include "scene/resources/packed_scene.h" #include "io/resource_loader.h" +#include "viewport.h" VARIANT_ENUM_CAST(Node::PauseMode); @@ -76,12 +77,25 @@ void Node::_notification(int p_notification) { data.pause_owner=this; } + if (data.input) + add_to_group("_vp_input"+itos(get_viewport()->get_instance_ID())); + if (data.unhandled_input) + add_to_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID())); + if (data.unhandled_key_input) + add_to_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID())); + get_scene()->node_count++; } break; case NOTIFICATION_EXIT_SCENE: { get_scene()->node_count--; + if (data.input) + remove_from_group("_vp_input"+itos(get_viewport()->get_instance_ID())); + if (data.unhandled_input) + remove_from_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID())); + if (data.unhandled_key_input) + remove_from_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID())); } break; case NOTIFICATION_READY: { @@ -148,6 +162,9 @@ void Node::_propagate_enter_scene() { data.depth=1; } + data.viewport = cast_to<Viewport>(); + if (!data.viewport) + data.viewport = data.parent->data.viewport; data.inside_scene=true; @@ -158,6 +175,7 @@ void Node::_propagate_enter_scene() { data.scene->add_to_group(*K,this); } + notification(NOTIFICATION_ENTER_SCENE); if (get_script_instance()) { @@ -216,6 +234,8 @@ void Node::_propagate_exit_scene() { data.scene->remove_from_group(*K,this); } + data.viewport = NULL; + if (data.scene) data.scene->tree_changed(); @@ -324,7 +344,7 @@ void Node::set_pause_mode(PauseMode p_mode) { if (data.pause_mode==PAUSE_MODE_INHERIT) { if (data.parent) - data.parent->data.pause_owner; + owner=data.parent->data.pause_owner; } else { owner=this; } @@ -421,11 +441,17 @@ void Node::set_process_input(bool p_enable) { if (p_enable==data.input) return; + data.input=p_enable; + if (!is_inside_scene()) + return; + if (p_enable) - add_to_group("input"); + add_to_group("_vp_input"+itos(get_viewport()->get_instance_ID())); else - remove_from_group("input"); + remove_from_group("_vp_input"+itos(get_viewport()->get_instance_ID())); + + } bool Node::is_processing_input() const { @@ -437,18 +463,41 @@ void Node::set_process_unhandled_input(bool p_enable) { if (p_enable==data.unhandled_input) return; data.unhandled_input=p_enable; + if (!is_inside_scene()) + return; if (p_enable) - add_to_group("unhandled_input"); + add_to_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID())); else - remove_from_group("unhandled_input"); + remove_from_group("_vp_unhandled_input"+itos(get_viewport()->get_instance_ID())); } + bool Node::is_processing_unhandled_input() const { return data.unhandled_input; } +void Node::set_process_unhandled_key_input(bool p_enable) { + + if (p_enable==data.unhandled_key_input) + return; + data.unhandled_key_input=p_enable; + if (!is_inside_scene()) + return; + + if (p_enable) + add_to_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID())); + else + remove_from_group("_vp_unhandled_key_input"+itos(get_viewport()->get_instance_ID())); +} + + +bool Node::is_processing_unhandled_key_input() const { + return data.unhandled_key_input; +} + + StringName Node::get_name() const { return data.name; @@ -1682,6 +1731,8 @@ void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("is_processing_input"),&Node::is_processing_input); ObjectTypeDB::bind_method(_MD("set_process_unhandled_input","enable"),&Node::set_process_unhandled_input); ObjectTypeDB::bind_method(_MD("is_processing_unhandled_input"),&Node::is_processing_unhandled_input); + ObjectTypeDB::bind_method(_MD("set_process_unhandled_key_input","enable"),&Node::set_process_unhandled_key_input); + ObjectTypeDB::bind_method(_MD("is_processing_unhandled_key_input"),&Node::is_processing_unhandled_key_input); ObjectTypeDB::bind_method(_MD("set_pause_mode","mode"),&Node::set_pause_mode); ObjectTypeDB::bind_method(_MD("get_pause_mode"),&Node::get_pause_mode); ObjectTypeDB::bind_method(_MD("can_process"),&Node::can_process); @@ -1693,6 +1744,8 @@ void Node::_bind_methods() { ObjectTypeDB::bind_method(_MD("duplicate:Node"),&Node::duplicate); ObjectTypeDB::bind_method(_MD("replace_by","node:Node","keep_data"),&Node::replace_by,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport); + ObjectTypeDB::bind_method(_MD("queue_free"),&Node::queue_delete); BIND_CONSTANT( NOTIFICATION_ENTER_SCENE ); @@ -1748,13 +1801,15 @@ Node::Node() { data.inside_scene=false; data.owner=NULL; - data.OW=false; + data.OW=NULL; data.input=false; data.unhandled_input=false; + data.unhandled_key_input=false; data.pause_mode=PAUSE_MODE_INHERIT; data.pause_owner=NULL; data.parent_owned=false; data.in_constructor=true; + data.viewport=NULL; } Node::~Node() { diff --git a/scene/main/node.h b/scene/main/node.h index 828acb8de7..b8981d3307 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -37,6 +37,7 @@ #include "scene/main/scene_main_loop.h" +class Viewport; class Node : public Object { OBJ_TYPE( Node, Object ); @@ -82,6 +83,8 @@ private: SceneMainLoop *scene; bool inside_scene; + Viewport *viewport; + HashMap< StringName, GroupData,StringNameHasher> grouped; List<Node*>::Element *OW; // owned element @@ -95,6 +98,7 @@ private: bool input; bool unhandled_input; + bool unhandled_key_input; bool parent_owned; bool in_constructor; @@ -237,6 +241,9 @@ public: void set_process_unhandled_input(bool p_enable); bool is_processing_unhandled_input() const; + void set_process_unhandled_key_input(bool p_enable); + bool is_processing_unhandled_key_input() const; + int get_position_in_parent() const; Node *duplicate() const; @@ -266,6 +273,8 @@ public: void force_parent_owned() { data.parent_owned=true; } //hack to avoid duplicate nodes + _FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; } + /* CANVAS */ Node(); diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp index cb3188b3b4..32bc4b3e16 100644 --- a/scene/main/scene_main_loop.cpp +++ b/scene/main/scene_main_loop.cpp @@ -340,7 +340,7 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) { InputEvent ev = p_event; - +#if 0 switch(ev.type) { case InputEvent::MOUSE_BUTTON: { @@ -391,15 +391,12 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) { } break; } - +#endif MainLoop::input_event(p_event); - +#if 0 _call_input_pause("input","_input",ev); - - - call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"_gui_input","_gui_input",p_event); //special one for GUI, as controls use their own process check //call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input","_input",ev); @@ -416,7 +413,11 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) { //} //transform for the rest +#else + + call_group(GROUP_CALL_REALTIME,"_viewports","_vp_input",p_event); //special one for GUI, as controls use their own process check +#endif if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote() && ev.type==InputEvent::KEY && ev.key.pressed && !ev.key.echo && ev.key.scancode==KEY_F8) { ScriptDebugger::get_singleton()->request_quit(); @@ -429,13 +430,19 @@ void SceneMainLoop::input_event( const InputEvent& p_event ) { root_lock++; if (!input_handled) { + +#if 0 _call_input_pause("unhandled_input","_unhandled_input",ev); //call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev); if (!input_handled && ev.type==InputEvent::KEY) { _call_input_pause("unhandled_key_input","_unhandled_key_input",ev); //call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev); } +#else + + call_group(GROUP_CALL_REALTIME,"_viewports","_vp_unhandled_input",p_event); //special one for GUI, as controls use their own process check +#endif input_handled=true; _flush_ugc(); root_lock--; diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h index a3776152ce..1c8e0c90ae 100644 --- a/scene/main/scene_main_loop.h +++ b/scene/main/scene_main_loop.h @@ -129,6 +129,8 @@ friend class Node; //optimization friend class CanvasItem; friend class Spatial; +friend class Viewport; + SelfList<Node>::List xform_change_list; protected: diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 4aed217cef..56d0544abd 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -129,6 +129,9 @@ void Viewport::_update_rect() { } emit_signal("size_changed"); + render_target_texture->emit_changed(); + + } void Viewport::_parent_resized() { @@ -658,6 +661,7 @@ void Viewport::set_size_override(bool p_enable, const Size2& p_size, const Vecto _update_rect(); _update_stretch_transform(); + } Size2 Viewport::get_size_override() const { @@ -711,6 +715,8 @@ void Viewport::set_as_render_target(bool p_enable){ render_target_texture_rid=RID(); } + + render_target_texture->emit_changed(); } bool Viewport::is_set_as_render_target() const{ @@ -743,6 +749,120 @@ Ref<RenderTargetTexture> Viewport::get_render_target_texture() const { return render_target_texture; } +void Viewport::set_render_target_vflip(bool p_enable) { + + render_target_vflip=p_enable; + VisualServer::get_singleton()->viewport_set_render_target_vflip(viewport,p_enable); +} + +bool Viewport::get_render_target_vflip() const{ + + return render_target_vflip; +} + + +void Viewport::_make_input_local(InputEvent& ev) { + + switch(ev.type) { + + case InputEvent::MOUSE_BUTTON: { + + Matrix32 ai = get_final_transform().affine_inverse(); + Vector2 g = ai.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y)); + Vector2 l = ai.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y)); + ev.mouse_button.x=l.x; + ev.mouse_button.y=l.y; + ev.mouse_button.global_x=g.x; + ev.mouse_button.global_y=g.y; + + } break; + case InputEvent::MOUSE_MOTION: { + + Matrix32 ai = get_final_transform().affine_inverse(); + Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y)); + Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y)); + Vector2 r = ai.xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y)); + ev.mouse_motion.x=l.x; + ev.mouse_motion.y=l.y; + ev.mouse_motion.global_x=g.x; + ev.mouse_motion.global_y=g.y; + ev.mouse_motion.relative_x=r.x; + ev.mouse_motion.relative_y=r.y; + + } break; + case InputEvent::SCREEN_TOUCH: { + + Matrix32 ai = get_final_transform().affine_inverse(); + Vector2 t = ai.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y)); + ev.screen_touch.x=t.x; + ev.screen_touch.y=t.y; + + } break; + case InputEvent::SCREEN_DRAG: { + + Matrix32 ai = get_final_transform().affine_inverse(); + Vector2 t = ai.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y)); + Vector2 r = ai.xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y)); + Vector2 s = ai.xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y)); + ev.screen_drag.x=t.x; + ev.screen_drag.y=t.y; + ev.screen_drag.relative_x=r.x; + ev.screen_drag.relative_y=r.y; + ev.screen_drag.speed_x=s.x; + ev.screen_drag.speed_y=s.y; + } break; + } + +} + + +void Viewport::_vp_input(const InputEvent& p_ev) { + + if (render_target) + return; //if render target, can't get input events + + //this one handles system input, p_ev are in system coordinates + //they are converted to viewport coordinates + + InputEvent ev = p_ev; + _make_input_local(ev); + input(ev); + +} + +void Viewport::_vp_unhandled_input(const InputEvent& p_ev) { + + if (render_target) + return; //if render target, can't get input events + + //this one handles system input, p_ev are in system coordinates + //they are converted to viewport coordinates + + InputEvent ev = p_ev; + _make_input_local(ev); + unhandled_input(ev); + +} + +void Viewport::input(const InputEvent& p_event) { + + ERR_FAIL_COND(!is_inside_scene()); + get_scene()->_call_input_pause(input_group,"_input",p_event); + get_scene()->call_group(SceneMainLoop::GROUP_CALL_REVERSE|SceneMainLoop::GROUP_CALL_REALTIME|SceneMainLoop::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check +} + +void Viewport::unhandled_input(const InputEvent& p_event) { + + ERR_FAIL_COND(!is_inside_scene()); + + get_scene()->_call_input_pause(unhandled_input_group,"_unhandled_input",p_event); + //call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev); + if (!get_scene()->input_handled && p_event.type==InputEvent::KEY) { + get_scene()->_call_input_pause(unhandled_key_input_group,"_unhandled_key_input",p_event); + //call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev); + } +} + void Viewport::_bind_methods() { @@ -770,6 +890,8 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("_parent_visibility_changed"), &Viewport::_parent_visibility_changed); ObjectTypeDB::bind_method(_MD("_parent_resized"), &Viewport::_parent_resized); + ObjectTypeDB::bind_method(_MD("_vp_input"), &Viewport::_vp_input); + ObjectTypeDB::bind_method(_MD("_vp_unhandled_input"), &Viewport::_vp_unhandled_input); ObjectTypeDB::bind_method(_MD("set_size_override","enable","size","margin"), &Viewport::set_size_override,DEFVAL(Size2(-1,-1)),DEFVAL(Size2(0,0))); ObjectTypeDB::bind_method(_MD("get_size_override"), &Viewport::get_size_override); @@ -782,14 +904,17 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_as_render_target","enable"), &Viewport::set_as_render_target); ObjectTypeDB::bind_method(_MD("is_set_as_render_target"), &Viewport::is_set_as_render_target); + ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip); + ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip); + ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode); ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode); ObjectTypeDB::bind_method(_MD("get_render_target_texture:RenderTargetTexture"), &Viewport::get_render_target_texture); - ObjectTypeDB::bind_method(_MD("get_viewport"), &Viewport::get_viewport); - + ObjectTypeDB::bind_method(_MD("input","local_event"), &Viewport::input); + ObjectTypeDB::bind_method(_MD("unhandled_input","local_event"), &Viewport::unhandled_input); ObjectTypeDB::bind_method(_MD("update_worlds"), &Viewport::update_worlds); @@ -806,6 +931,7 @@ void Viewport::_bind_methods() { // ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"world_2d",PROPERTY_HINT_RESOURCE_TYPE,"World2D"), _SCS("set_world_2d"), _SCS("get_world_2d") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") ); ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") ); @@ -839,10 +965,15 @@ Viewport::Viewport() { size_override_stretch=false; size_override_size=Size2(1,1); render_target=false; + render_target_vflip=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) ); - + String id=itos(get_instance_ID()); + input_group = "_vp_input"+id; + gui_input_group = "_vp_gui_input"+id; + unhandled_input_group = "_vp_unhandled_input"+id; + unhandled_key_input_group = "_vp_unhandled_key_input"+id; } diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 7fbae20f7d..8ba84651f8 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -110,6 +110,7 @@ friend class RenderTargetTexture; bool transparent_bg; + bool render_target_vflip; void _update_rect(); @@ -120,6 +121,11 @@ friend class RenderTargetTexture; Ref<World2D> world_2d; Ref<World> world; + StringName input_group; + StringName gui_input_group; + StringName unhandled_input_group; + StringName unhandled_key_input_group; + void _update_listener(); void _update_listener_2d(); @@ -142,6 +148,10 @@ friend class RenderTargetTexture; void _vp_enter_scene(); void _vp_exit_scene(); + void _vp_input(const InputEvent& p_ev); + void _vp_unhandled_input(const InputEvent& p_ev); + void _make_input_local(InputEvent& ev); + friend class Camera; void _camera_transform_changed_notify(); void _set_camera(Camera* p_camera); @@ -190,10 +200,12 @@ public: void set_size_override_stretch(bool p_enable); bool is_size_override_stretch_enabled() const; - - void set_as_render_target(bool p_enable); bool is_set_as_render_target() const; + + void set_render_target_vflip(bool p_enable); + bool get_render_target_vflip() const; + void set_render_target_update_mode(RenderTargetUpdateMode p_mode); RenderTargetUpdateMode get_render_target_update_mode() const; Ref<RenderTargetTexture> get_render_target_texture() const; @@ -201,6 +213,9 @@ public: void queue_screen_capture(); Image get_screen_capture() const; + void input(const InputEvent& p_event); + void unhandled_input(const InputEvent& p_event); + Viewport(); ~Viewport(); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 007ecb88b7..8fd39b0d74 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -446,6 +446,7 @@ void register_scene_types() { ObjectTypeDB::register_type<Particles2D>(); ObjectTypeDB::register_type<ParticleAttractor2D>(); ObjectTypeDB::register_type<Sprite>(); + ObjectTypeDB::register_type<ViewportSprite>(); ObjectTypeDB::register_type<SpriteFrames>(); ObjectTypeDB::register_type<AnimatedSprite>(); ObjectTypeDB::register_type<Position2D>(); diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 3c992a93b9..d10bb37f60 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -583,7 +583,7 @@ void make_default_theme() { t->set_stylebox("panel","PanelContainer", tc_sb ); - t->set_stylebox( "logo","Icons", make_icon(logo_png) ); + t->set_icon( "logo","Icons", make_icon(logo_png) ); Theme::set_default( t ); Theme::set_default_icon( make_icon(error_icon_png) ); |