summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/canvas_item.cpp19
-rw-r--r--scene/2d/canvas_item.h2
-rw-r--r--scene/animation/animation_tree_player.cpp2
-rw-r--r--scene/gui/control.cpp50
-rw-r--r--scene/gui/control.h2
-rw-r--r--scene/gui/rich_text_label.cpp7
-rw-r--r--scene/gui/text_edit.cpp16
-rw-r--r--scene/main/node.cpp17
-rw-r--r--scene/resources/dynamic_font.cpp6
9 files changed, 98 insertions, 23 deletions
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index 17e5503a2d..8864459dfb 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -1042,7 +1042,9 @@ void CanvasItem::_bind_methods() {
ObjectTypeDB::bind_method(_MD("edit_rotate","degrees"),&CanvasItem::edit_rotate);
ObjectTypeDB::bind_method(_MD("get_item_rect"),&CanvasItem::get_item_rect);
+ ObjectTypeDB::bind_method(_MD("get_item_and_children_rect"),&CanvasItem::get_item_and_children_rect);
//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
+
ObjectTypeDB::bind_method(_MD("get_canvas_item"),&CanvasItem::get_canvas_item);
ObjectTypeDB::bind_method(_MD("is_visible"),&CanvasItem::is_visible);
@@ -1195,6 +1197,23 @@ int CanvasItem::get_canvas_layer() const {
return 0;
}
+
+Rect2 CanvasItem::get_item_and_children_rect() const {
+
+ Rect2 rect = get_item_rect();
+
+
+ for(int i=0;i<get_child_count();i++) {
+ CanvasItem *c=get_child(i)->cast_to<CanvasItem>();
+ if (c) {
+ Rect2 sir = c->get_transform().xform(c->get_item_and_children_rect());
+ rect = rect.merge(sir);
+ }
+ }
+
+ return rect;
+}
+
CanvasItem::CanvasItem() : xform_change(this) {
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 05a2e725e9..d915f742ec 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -240,6 +240,8 @@ public:
virtual Matrix32 get_global_transform() const;
virtual Matrix32 get_global_transform_with_canvas() const;
+ Rect2 get_item_and_children_rect() const;
+
CanvasItem *get_toplevel() const;
_FORCE_INLINE_ RID get_canvas_item() const { return canvas_item; }
diff --git a/scene/animation/animation_tree_player.cpp b/scene/animation/animation_tree_player.cpp
index 211c5961b0..0f7ed1cb29 100644
--- a/scene/animation/animation_tree_player.cpp
+++ b/scene/animation/animation_tree_player.cpp
@@ -669,7 +669,7 @@ float AnimationTreePlayer::_process_node(const StringName& p_node,AnimationNode
}
tsn->seek_pos=-1;
- return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek);
+ return _process_node(tsn->inputs[0].node,r_prev_anim,p_weight,p_time,p_seek, p_filter, p_reverse_weight);
} break;
case NODE_TRANSITION: {
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index dfad7d1432..666ac88055 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -437,11 +437,17 @@ void Control::_notification(int p_notification) {
if (is_set_as_toplevel()) {
data.SI=get_viewport()->_gui_add_subwindow_control(this);
+
+ if (data.theme.is_null() && data.parent && data.parent->data.theme_owner) {
+ data.theme_owner=data.parent->data.theme_owner;
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
+
} else {
Node *parent=this; //meh
- Node *parent_control=NULL;
+ Control *parent_control=NULL;
bool subwindow=false;
while(parent) {
@@ -457,8 +463,9 @@ void Control::_notification(int p_notification) {
break;
}
- if (parent->cast_to<Control>()) {
- parent_control=parent->cast_to<Control>();
+ parent_control=parent->cast_to<Control>();
+
+ if (parent_control) {
break;
} else if (ci) {
@@ -470,6 +477,10 @@ void Control::_notification(int p_notification) {
if (parent_control) {
//do nothing, has a parent control
+ if (data.theme.is_null() && parent_control->data.theme_owner) {
+ data.theme_owner=parent_control->data.theme_owner;
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
} else if (subwindow) {
//is a subwindow (process input before other controls for that canvas)
data.SI=get_viewport()->_gui_add_subwindow_control(this);
@@ -1829,18 +1840,29 @@ void Control::_modal_stack_remove() {
}
-void Control::_propagate_theme_changed(Control *p_owner) {
+void Control::_propagate_theme_changed(CanvasItem *p_at,Control *p_owner) {
+
+ Control *c = p_at->cast_to<Control>();
+
+ if (c && c!=p_owner && c->data.theme.is_valid()) // has a theme, this can't be propagated
+ return;
+
+ for(int i=0;i<p_at->get_child_count();i++) {
- for(int i=0;i<get_child_count();i++) {
+ CanvasItem *child = p_at->get_child(i)->cast_to<CanvasItem>();
+ if (child) {
+ _propagate_theme_changed(child,p_owner);
+ }
- Control *child = get_child(i)->cast_to<Control>();
- if (child && child->data.theme.is_null()) //has no theme, propagate
- child->_propagate_theme_changed(p_owner);
}
- data.theme_owner=p_owner;
- _notification(NOTIFICATION_THEME_CHANGED);
- update();
+
+ if (c) {
+
+ c->data.theme_owner=p_owner;
+ c->_notification(NOTIFICATION_THEME_CHANGED);
+ c->update();
+ }
}
void Control::set_theme(const Ref<Theme>& p_theme) {
@@ -1849,15 +1871,15 @@ void Control::set_theme(const Ref<Theme>& p_theme) {
data.theme=p_theme;
if (!p_theme.is_null()) {
- _propagate_theme_changed(this);
+ _propagate_theme_changed(this,this);
} else {
Control *parent = get_parent()?get_parent()->cast_to<Control>():NULL;
if (parent && parent->data.theme_owner) {
- _propagate_theme_changed(parent->data.theme_owner);
+ _propagate_theme_changed(this,parent->data.theme_owner);
} else {
- _propagate_theme_changed(NULL);
+ _propagate_theme_changed(this,NULL);
}
}
diff --git a/scene/gui/control.h b/scene/gui/control.h
index 59704ae29b..69ee41f180 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -169,7 +169,7 @@ private:
float _get_range(int p_idx) const;
float _s2a(float p_val, AnchorType p_anchor,float p_range) const;
float _a2s(float p_val, AnchorType p_anchor,float p_range) const;
- void _propagate_theme_changed(Control *p_owner);
+ void _propagate_theme_changed(CanvasItem *p_at, Control *p_owner);
void _change_notify_margins();
void _update_minimum_size();
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 80949b4eb4..786ce27a0c 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -278,6 +278,11 @@ if (m_height > line_height) {\
if (c[end]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
+
+ if (end>0 && w+cw+begin > p_width ) {
+ break; //don't allow lines longer than assigned width
+ }
+
w+=cw;
if (c[end]==' ') {
@@ -340,10 +345,12 @@ if (m_height > line_height) {\
int cw=font->get_char_size(c[i],c[i+1]).x;
+
if (c[i]=='\t') {
cw=tab_size*font->get_char_size(' ').width;
}
+
if (p_click_pos.x-cw/2>p_ofs.x+align_ofs+pofs) {
rchar=int((&c[i])-cf);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 3d3ef46465..49d7527786 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -3825,12 +3825,16 @@ void TextEdit::undo() {
_do_text_op(op, true);
current_op.version=op.prev_version;
if(undo_stack_pos->get().chain_backward) {
- do {
+ while(true) {
+ ERR_BREAK(!undo_stack_pos->prev());
undo_stack_pos = undo_stack_pos->prev();
op = undo_stack_pos->get();
_do_text_op(op, true);
current_op.version = op.prev_version;
- } while(!undo_stack_pos->get().chain_forward);
+ if (undo_stack_pos->get().chain_forward) {
+ break;
+ }
+ }
}
cursor_set_line(undo_stack_pos->get().from_line);
@@ -3849,12 +3853,16 @@ void TextEdit::redo() {
_do_text_op(op, false);
current_op.version = op.version;
if(undo_stack_pos->get().chain_forward) {
- do {
+
+ while(true) {
+ ERR_BREAK(!undo_stack_pos->next());
undo_stack_pos=undo_stack_pos->next();
op = undo_stack_pos->get();
_do_text_op(op, false);
current_op.version = op.version;
- } while(!undo_stack_pos->get().chain_backward);
+ if (undo_stack_pos->get().chain_backward)
+ break;
+ }
}
cursor_set_line(undo_stack_pos->get().to_line);
cursor_set_column(undo_stack_pos->get().to_column);
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index cfc7116d19..50b0fe224e 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -283,7 +283,11 @@ void Node::move_child(Node *p_child,int p_pos) {
ERR_FAIL_INDEX( p_pos, data.children.size()+1 );
ERR_EXPLAIN("child is not a child of this node.");
ERR_FAIL_COND(p_child->data.parent!=this);
- ERR_FAIL_COND(data.blocked>0);
+ if (data.blocked>0) {
+ ERR_EXPLAIN("Parent node is busy setting up children, move_child() failed. Consider using call_deferred(\"move_child\") instead (or \"popup\" if this is from a popup).");
+ ERR_FAIL_COND(data.blocked>0);
+ }
+
data.children.remove( p_child->data.pos );
data.children.insert( p_pos, p_child );
@@ -739,6 +743,12 @@ void Node::add_child(Node *p_child, bool p_legible_unique_name) {
}
ERR_EXPLAIN("Can't add child, already has a parent");
ERR_FAIL_COND( p_child->data.parent );
+
+ if (data.blocked>0) {
+ ERR_EXPLAIN("Parent node is busy setting up children, add_node() failed. Consider using call_deferred(\"add_child\",child) instead.");
+ ERR_FAIL_COND(data.blocked>0);
+ }
+
ERR_EXPLAIN("Can't add child while a notification is happening");
ERR_FAIL_COND( data.blocked > 0 );
@@ -800,7 +810,10 @@ void Node::_propagate_validate_owner() {
void Node::remove_child(Node *p_child) {
ERR_FAIL_NULL(p_child);
- ERR_FAIL_COND( data.blocked > 0 );
+ if (data.blocked>0) {
+ ERR_EXPLAIN("Parent node is busy setting up children, remove_node() failed. Consider using call_deferred(\"remove_child\",child) instead.");
+ ERR_FAIL_COND(data.blocked>0);
+ }
int idx=-1;
for (int i=0;i<data.children.size();i++) {
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 78a5571bf0..1edae01754 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -573,7 +573,11 @@ DynamicFontAtSize::~DynamicFontAtSize(){
void DynamicFont::set_font_data(const Ref<DynamicFontData>& p_data) {
data=p_data;
- data_at_size=data->_get_dynamic_font_at_size(size);
+ if (data.is_valid())
+ data_at_size=data->_get_dynamic_font_at_size(size);
+ else
+ data_at_size=Ref<DynamicFontAtSize>();
+
emit_changed();
}