Backport CanvasLayer visibility
This commit is contained in:
parent
0c7c640112
commit
f49ffe4bb0
@ -47,7 +47,18 @@
|
|||||||
<member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
|
<member name="transform" type="Transform2D" setter="set_transform" getter="get_transform" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
|
||||||
The layer's transform.
|
The layer's transform.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="visible" type="bool" setter="set_visible" getter="is_visible" default="true">
|
||||||
|
If [code]false[/code], any [CanvasItem] under this [CanvasLayer] will be hidden.
|
||||||
|
Unlike [member CanvasItem.visible], visibility of a [CanvasLayer] isn't propagated to underlying layers.
|
||||||
|
</member>
|
||||||
</members>
|
</members>
|
||||||
|
<signals>
|
||||||
|
<signal name="visibility_changed">
|
||||||
|
<description>
|
||||||
|
Emitted when visibility of the layer is changed. See [member visible].
|
||||||
|
</description>
|
||||||
|
</signal>
|
||||||
|
</signals>
|
||||||
<constants>
|
<constants>
|
||||||
</constants>
|
</constants>
|
||||||
</class>
|
</class>
|
||||||
|
@ -361,6 +361,17 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent, bool p_scroll
|
|||||||
}
|
}
|
||||||
|
|
||||||
_update_visibility_color(p_node, item);
|
_update_visibility_color(p_node, item);
|
||||||
|
} else if (p_node->is_class("CanvasLayer")) {
|
||||||
|
bool v = p_node->call("is_visible");
|
||||||
|
if (v) {
|
||||||
|
item->add_button(0, get_icon("GuiVisibilityVisible", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
|
||||||
|
} else {
|
||||||
|
item->add_button(0, get_icon("GuiVisibilityHidden", "EditorIcons"), BUTTON_VISIBILITY, false, TTR("Toggle Visibility"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!p_node->is_connected("visibility_changed", this, "_node_visibility_changed")) {
|
||||||
|
p_node->connect("visibility_changed", this, "_node_visibility_changed", varray(p_node));
|
||||||
|
}
|
||||||
} else if (p_node->is_class("Spatial")) {
|
} else if (p_node->is_class("Spatial")) {
|
||||||
bool is_locked = p_node->has_meta("_edit_lock_");
|
bool is_locked = p_node->has_meta("_edit_lock_");
|
||||||
if (is_locked) {
|
if (is_locked) {
|
||||||
@ -470,6 +481,9 @@ void SceneTreeEditor::_node_visibility_changed(Node *p_node) {
|
|||||||
if (p_node->is_class("CanvasItem")) {
|
if (p_node->is_class("CanvasItem")) {
|
||||||
visible = p_node->call("is_visible");
|
visible = p_node->call("is_visible");
|
||||||
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
|
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
|
||||||
|
} else if (p_node->is_class("CanvasLayer")) {
|
||||||
|
visible = p_node->call("is_visible");
|
||||||
|
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
|
||||||
} else if (p_node->is_class("Spatial")) {
|
} else if (p_node->is_class("Spatial")) {
|
||||||
visible = p_node->call("is_visible");
|
visible = p_node->call("is_visible");
|
||||||
}
|
}
|
||||||
@ -528,7 +542,7 @@ void SceneTreeEditor::_node_removed(Node *p_node) {
|
|||||||
p_node->disconnect("script_changed", this, "_node_script_changed");
|
p_node->disconnect("script_changed", this, "_node_script_changed");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p_node->is_class("Spatial") || p_node->is_class("CanvasItem")) {
|
if (p_node->is_class("Spatial") || p_node->is_class("CanvasItem") || p_node->is_class("CanvasLayer")) {
|
||||||
if (p_node->is_connected("visibility_changed", this, "_node_visibility_changed")) {
|
if (p_node->is_connected("visibility_changed", this, "_node_visibility_changed")) {
|
||||||
p_node->disconnect("visibility_changed", this, "_node_visibility_changed");
|
p_node->disconnect("visibility_changed", this, "_node_visibility_changed");
|
||||||
}
|
}
|
||||||
|
@ -350,31 +350,19 @@ Transform2D CanvasItem::_edit_get_transform() const {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool CanvasItem::is_visible_in_tree() const {
|
bool CanvasItem::is_visible_in_tree() const {
|
||||||
if (!is_inside_tree()) {
|
return visible && parent_visible_in_tree;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CanvasItem *p = this;
|
|
||||||
|
|
||||||
while (p) {
|
|
||||||
if (!p->visible) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
p = p->get_parent_item();
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItem::_propagate_visibility_changed(bool p_visible) {
|
void CanvasItem::_propagate_visibility_changed(bool p_visible, bool p_was_visible) {
|
||||||
if (p_visible && first_draw) { //avoid propagating it twice
|
if (p_visible && first_draw) { //avoid propagating it twice
|
||||||
first_draw = false;
|
first_draw = false;
|
||||||
}
|
}
|
||||||
|
parent_visible_in_tree = p_visible;
|
||||||
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
||||||
|
|
||||||
if (p_visible) {
|
if (visible && p_visible) {
|
||||||
update(); //todo optimize
|
update();
|
||||||
} else {
|
} else if (!p_visible && (visible || p_was_visible)) {
|
||||||
emit_signal(SceneStringNames::get_singleton()->hide);
|
emit_signal(SceneStringNames::get_singleton()->hide);
|
||||||
}
|
}
|
||||||
_block();
|
_block();
|
||||||
@ -383,43 +371,39 @@ void CanvasItem::_propagate_visibility_changed(bool p_visible) {
|
|||||||
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
|
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
|
||||||
|
|
||||||
if (c && c->visible) { //should the toplevels stop propagation? i think so but..
|
if (c && c->visible) { //should the toplevels stop propagation? i think so but..
|
||||||
c->_propagate_visibility_changed(p_visible);
|
c->_propagate_visibility_changed(p_visible, !p_visible);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_unblock();
|
_unblock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItem::show() {
|
void CanvasItem::set_visible(bool p_visible) {
|
||||||
if (visible) {
|
if (visible == p_visible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
visible = true;
|
visible = p_visible;
|
||||||
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, true);
|
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, p_visible);
|
||||||
|
|
||||||
if (!is_inside_tree()) {
|
if (!is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_propagate_visibility_changed(true);
|
_propagate_visibility_changed(p_visible, !p_visible);
|
||||||
_change_notify("visible");
|
_change_notify("visible");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasItem::show() {
|
||||||
|
set_visible(true);
|
||||||
|
}
|
||||||
|
|
||||||
void CanvasItem::hide() {
|
void CanvasItem::hide() {
|
||||||
if (!visible) {
|
set_visible(false);
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
visible = false;
|
bool CanvasItem::is_visible() const {
|
||||||
VisualServer::get_singleton()->canvas_item_set_visible(canvas_item, false);
|
return visible;
|
||||||
|
|
||||||
if (!is_inside_tree()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_propagate_visibility_changed(false);
|
|
||||||
_change_notify("visible");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CanvasItem *CanvasItem::current_item_drawn = nullptr;
|
CanvasItem *CanvasItem::current_item_drawn = nullptr;
|
||||||
@ -435,7 +419,7 @@ void CanvasItem::_update_callback() {
|
|||||||
|
|
||||||
VisualServer::get_singleton()->canvas_item_clear(get_canvas_item());
|
VisualServer::get_singleton()->canvas_item_clear(get_canvas_item());
|
||||||
//todo updating = true - only allow drawing here
|
//todo updating = true - only allow drawing here
|
||||||
if (is_visible_in_tree()) { //todo optimize this!!
|
if (is_visible_in_tree()) {
|
||||||
if (first_draw) {
|
if (first_draw) {
|
||||||
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
notification(NOTIFICATION_VISIBILITY_CHANGED);
|
||||||
first_draw = false;
|
first_draw = false;
|
||||||
@ -556,10 +540,20 @@ void CanvasItem::_notification(int p_what) {
|
|||||||
case NOTIFICATION_ENTER_TREE: {
|
case NOTIFICATION_ENTER_TREE: {
|
||||||
ERR_FAIL_COND(!is_inside_tree());
|
ERR_FAIL_COND(!is_inside_tree());
|
||||||
first_draw = true;
|
first_draw = true;
|
||||||
if (get_parent()) {
|
|
||||||
CanvasItem *ci = Object::cast_to<CanvasItem>(get_parent());
|
Node *parent = get_parent();
|
||||||
|
if (parent) {
|
||||||
|
CanvasItem *ci = Object::cast_to<CanvasItem>(parent);
|
||||||
if (ci) {
|
if (ci) {
|
||||||
|
parent_visible_in_tree = ci->is_visible_in_tree();
|
||||||
C = ci->children_items.push_back(this);
|
C = ci->children_items.push_back(this);
|
||||||
|
} else {
|
||||||
|
CanvasLayer *cl = Object::cast_to<CanvasLayer>(parent);
|
||||||
|
if (cl) {
|
||||||
|
parent_visible_in_tree = cl->is_visible();
|
||||||
|
} else {
|
||||||
|
parent_visible_in_tree = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_enter_canvas();
|
_enter_canvas();
|
||||||
@ -591,6 +585,7 @@ void CanvasItem::_notification(int p_what) {
|
|||||||
C = nullptr;
|
C = nullptr;
|
||||||
}
|
}
|
||||||
global_invalid = true;
|
global_invalid = true;
|
||||||
|
parent_visible_in_tree = false;
|
||||||
} break;
|
} break;
|
||||||
case NOTIFICATION_DRAW:
|
case NOTIFICATION_DRAW:
|
||||||
case NOTIFICATION_TRANSFORM_CHANGED: {
|
case NOTIFICATION_TRANSFORM_CHANGED: {
|
||||||
@ -601,17 +596,6 @@ void CanvasItem::_notification(int p_what) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanvasItem::set_visible(bool p_visible) {
|
|
||||||
if (p_visible) {
|
|
||||||
show();
|
|
||||||
} else {
|
|
||||||
hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool CanvasItem::is_visible() const {
|
|
||||||
return visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CanvasItem::update() {
|
void CanvasItem::update() {
|
||||||
if (!is_inside_tree()) {
|
if (!is_inside_tree()) {
|
||||||
return;
|
return;
|
||||||
@ -1267,6 +1251,7 @@ CanvasItem::CanvasItem() :
|
|||||||
xform_change(this) {
|
xform_change(this) {
|
||||||
canvas_item = RID_PRIME(VisualServer::get_singleton()->canvas_item_create());
|
canvas_item = RID_PRIME(VisualServer::get_singleton()->canvas_item_create());
|
||||||
visible = true;
|
visible = true;
|
||||||
|
parent_visible_in_tree = false;
|
||||||
pending_update = false;
|
pending_update = false;
|
||||||
modulate = Color(1, 1, 1, 1);
|
modulate = Color(1, 1, 1, 1);
|
||||||
self_modulate = Color(1, 1, 1, 1);
|
self_modulate = Color(1, 1, 1, 1);
|
||||||
|
@ -162,6 +162,8 @@ VARIANT_ENUM_CAST(CanvasItemMaterial::LightMode)
|
|||||||
class CanvasItem : public Node {
|
class CanvasItem : public Node {
|
||||||
GDCLASS(CanvasItem, Node);
|
GDCLASS(CanvasItem, Node);
|
||||||
|
|
||||||
|
friend class CanvasLayer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum BlendMode {
|
enum BlendMode {
|
||||||
|
|
||||||
@ -191,6 +193,7 @@ private:
|
|||||||
|
|
||||||
bool first_draw;
|
bool first_draw;
|
||||||
bool visible;
|
bool visible;
|
||||||
|
bool parent_visible_in_tree;
|
||||||
bool pending_update;
|
bool pending_update;
|
||||||
bool toplevel;
|
bool toplevel;
|
||||||
bool drawing;
|
bool drawing;
|
||||||
@ -207,7 +210,7 @@ private:
|
|||||||
|
|
||||||
void _toplevel_raise_self();
|
void _toplevel_raise_self();
|
||||||
|
|
||||||
void _propagate_visibility_changed(bool p_visible);
|
void _propagate_visibility_changed(bool p_visible, bool p_was_visible = false);
|
||||||
|
|
||||||
void _update_callback();
|
void _update_callback();
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
/*************************************************************************/
|
/*************************************************************************/
|
||||||
|
|
||||||
#include "canvas_layer.h"
|
#include "canvas_layer.h"
|
||||||
|
#include "scene/2d/canvas_item.h"
|
||||||
#include "viewport.h"
|
#include "viewport.h"
|
||||||
|
|
||||||
void CanvasLayer::set_layer(int p_xform) {
|
void CanvasLayer::set_layer(int p_xform) {
|
||||||
@ -42,6 +43,32 @@ int CanvasLayer::get_layer() const {
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CanvasLayer::set_visible(bool p_visible) {
|
||||||
|
if (p_visible == visible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
visible = p_visible;
|
||||||
|
emit_signal("visibility_changed");
|
||||||
|
|
||||||
|
for (int i = 0; i < get_child_count(); i++) {
|
||||||
|
CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
|
||||||
|
if (c) {
|
||||||
|
VisualServer::get_singleton()->canvas_item_set_visible(c->get_canvas_item(), p_visible && c->is_visible());
|
||||||
|
|
||||||
|
if (c->is_visible()) {
|
||||||
|
c->_propagate_visibility_changed(p_visible);
|
||||||
|
} else {
|
||||||
|
c->notification(CanvasItem::NOTIFICATION_VISIBILITY_CHANGED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CanvasLayer::is_visible() const {
|
||||||
|
return visible;
|
||||||
|
}
|
||||||
|
|
||||||
void CanvasLayer::set_transform(const Transform2D &p_xform) {
|
void CanvasLayer::set_transform(const Transform2D &p_xform) {
|
||||||
transform = p_xform;
|
transform = p_xform;
|
||||||
locrotscale_dirty = true;
|
locrotscale_dirty = true;
|
||||||
@ -265,6 +292,9 @@ void CanvasLayer::_bind_methods() {
|
|||||||
ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
|
ClassDB::bind_method(D_METHOD("set_layer", "layer"), &CanvasLayer::set_layer);
|
||||||
ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer);
|
ClassDB::bind_method(D_METHOD("get_layer"), &CanvasLayer::get_layer);
|
||||||
|
|
||||||
|
ClassDB::bind_method(D_METHOD("set_visible", "visible"), &CanvasLayer::set_visible);
|
||||||
|
ClassDB::bind_method(D_METHOD("is_visible"), &CanvasLayer::is_visible);
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &CanvasLayer::set_transform);
|
ClassDB::bind_method(D_METHOD("set_transform", "transform"), &CanvasLayer::set_transform);
|
||||||
ClassDB::bind_method(D_METHOD("get_transform"), &CanvasLayer::get_transform);
|
ClassDB::bind_method(D_METHOD("get_transform"), &CanvasLayer::get_transform);
|
||||||
|
|
||||||
@ -293,6 +323,7 @@ void CanvasLayer::_bind_methods() {
|
|||||||
|
|
||||||
ADD_GROUP("Layer", "");
|
ADD_GROUP("Layer", "");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer");
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "layer", PROPERTY_HINT_RANGE, "-128,128,1"), "set_layer", "get_layer");
|
||||||
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
|
||||||
ADD_GROUP("Transform", "");
|
ADD_GROUP("Transform", "");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
|
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "rotation_degrees", PROPERTY_HINT_RANGE, "-1080,1080,0.1,or_lesser,or_greater", PROPERTY_USAGE_EDITOR), "set_rotation_degrees", "get_rotation_degrees");
|
||||||
@ -304,6 +335,8 @@ void CanvasLayer::_bind_methods() {
|
|||||||
ADD_GROUP("Follow Viewport", "follow_viewport");
|
ADD_GROUP("Follow Viewport", "follow_viewport");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enable"), "set_follow_viewport", "is_following_viewport");
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "follow_viewport_enable"), "set_follow_viewport", "is_following_viewport");
|
||||||
ADD_PROPERTY(PropertyInfo(Variant::REAL, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale");
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "follow_viewport_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001,or_greater,or_lesser"), "set_follow_viewport_scale", "get_follow_viewport_scale");
|
||||||
|
|
||||||
|
ADD_SIGNAL(MethodInfo("visibility_changed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
@ -326,6 +359,7 @@ CanvasLayer::CanvasLayer() {
|
|||||||
custom_viewport = nullptr;
|
custom_viewport = nullptr;
|
||||||
custom_viewport_id = 0;
|
custom_viewport_id = 0;
|
||||||
sort_index = 0;
|
sort_index = 0;
|
||||||
|
visible = true;
|
||||||
follow_viewport = false;
|
follow_viewport = false;
|
||||||
follow_viewport_scale = 1.0;
|
follow_viewport_scale = 1.0;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,7 @@ class CanvasLayer : public Node {
|
|||||||
Viewport *vp;
|
Viewport *vp;
|
||||||
|
|
||||||
int sort_index;
|
int sort_index;
|
||||||
|
bool visible;
|
||||||
|
|
||||||
bool follow_viewport;
|
bool follow_viewport;
|
||||||
float follow_viewport_scale;
|
float follow_viewport_scale;
|
||||||
@ -69,6 +70,9 @@ public:
|
|||||||
void set_layer(int p_xform);
|
void set_layer(int p_xform);
|
||||||
int get_layer() const;
|
int get_layer() const;
|
||||||
|
|
||||||
|
void set_visible(bool p_visible);
|
||||||
|
bool is_visible() const;
|
||||||
|
|
||||||
void set_transform(const Transform2D &p_xform);
|
void set_transform(const Transform2D &p_xform);
|
||||||
Transform2D get_transform() const;
|
Transform2D get_transform() const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user