summaryrefslogtreecommitdiff
path: root/scene/gui/control.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/control.cpp')
-rw-r--r--scene/gui/control.cpp253
1 files changed, 182 insertions, 71 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 73e7237058..edc8a8bcb8 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -153,6 +153,9 @@ bool Control::_set(const StringName& p_name, const Variant& p_value) {
update();
} else if (name.begins_with("custom_fonts/")) {
String dname = name.get_slicec('/',1);
+ if (data.font_override.has(dname)) {
+ _unref_font(data.font_override[dname]);
+ }
data.font_override.erase(dname);
notification(NOTIFICATION_THEME_CHANGED);
update();
@@ -223,7 +226,7 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
String sname=p_name;
- if (!sname.begins_with("custom"))
+ if (!sname.begins_with("custom")) {
if (sname.begins_with("margin/")) {
String dname = sname.get_slicec('/', 1);
if (dname == "left") {
@@ -248,6 +251,7 @@ bool Control::_get(const StringName& p_name,Variant &r_ret) const {
} else {
return false;
}
+ }
if (sname.begins_with("custom_icons/")) {
String name = sname.get_slicec('/',1);
@@ -436,11 +440,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) {
@@ -456,8 +466,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) {
@@ -469,6 +480,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);
@@ -489,6 +504,10 @@ void Control::_notification(int p_notification) {
}
+ if (data.theme.is_null() && data.parent && data.parent->data.theme_owner) {
+ data.theme_owner=data.parent->data.theme_owner;
+ notification(NOTIFICATION_THEME_CHANGED);
+ }
} break;
case NOTIFICATION_EXIT_CANVAS: {
@@ -520,26 +539,9 @@ void Control::_notification(int p_notification) {
data.parent=NULL;
data.parent_canvas_item=NULL;
-
- } break;
-
-
- case NOTIFICATION_PARENTED: {
-
- Control * parent = get_parent()->cast_to<Control>();
-
- //make children reference them theme
-
- if (parent && data.theme.is_null() && parent->data.theme_owner) {
- _propagate_theme_changed(parent->data.theme_owner);
- }
-
- } break;
- case NOTIFICATION_UNPARENTED: {
-
- //make children unreference the theme
- if (data.theme.is_null() && data.theme_owner) {
- _propagate_theme_changed(NULL);
+ if (data.theme_owner && data.theme.is_null()) {
+ data.theme_owner=NULL;
+ //notification(NOTIFICATION_THEME_CHANGED);
}
} break;
@@ -770,7 +772,7 @@ Size2 Control::get_minimum_size() const {
Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<Texture>* tex = data.icon_override.getptr(p_name);
if (tex)
@@ -785,7 +787,7 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type
while(theme_owner) {
if (theme_owner->data.theme->has_icon(p_name, type ) )
- return data.theme_owner->data.theme->get_icon(p_name, type );
+ return theme_owner->data.theme->get_icon(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -800,7 +802,7 @@ Ref<Texture> Control::get_icon(const StringName& p_name,const StringName& p_type
}
Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
if (sdr)
@@ -815,7 +817,7 @@ Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_typ
while(theme_owner) {
if (theme_owner->data.theme->has_shader(p_name, type))
- return data.theme_owner->data.theme->get_shader(p_name, type );
+ return theme_owner->data.theme->get_shader(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -830,7 +832,7 @@ Ref<Shader> Control::get_shader(const StringName& p_name,const StringName& p_typ
Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<StyleBox>* style = data.style_override.getptr(p_name);
if (style)
return *style;
@@ -843,8 +845,9 @@ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p
while(theme_owner) {
- if (theme_owner->data.theme->has_stylebox(p_name, type ) )
- return data.theme_owner->data.theme->get_stylebox(p_name, type );
+ if (theme_owner->data.theme->has_stylebox(p_name, type ) ) {
+ return theme_owner->data.theme->get_stylebox(p_name, type );
+ }
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -858,7 +861,7 @@ Ref<StyleBox> Control::get_stylebox(const StringName& p_name,const StringName& p
}
Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Ref<Font>* font = data.font_override.getptr(p_name);
if (font)
return *font;
@@ -872,7 +875,7 @@ Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) c
while(theme_owner) {
if (theme_owner->data.theme->has_font(p_name, type ) )
- return data.theme_owner->data.theme->get_font(p_name, type );
+ return theme_owner->data.theme->get_font(p_name, type );
if (theme_owner->data.theme->get_default_theme_font().is_valid())
return theme_owner->data.theme->get_default_theme_font();
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
@@ -889,7 +892,7 @@ Ref<Font> Control::get_font(const StringName& p_name,const StringName& p_type) c
}
Color Control::get_color(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const Color* color = data.color_override.getptr(p_name);
if (color)
return *color;
@@ -902,7 +905,7 @@ Color Control::get_color(const StringName& p_name,const StringName& p_type) cons
while(theme_owner) {
if (theme_owner->data.theme->has_color(p_name, type ) )
- return data.theme_owner->data.theme->get_color(p_name, type );
+ return theme_owner->data.theme->get_color(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -918,7 +921,7 @@ Color Control::get_color(const StringName& p_name,const StringName& p_type) cons
int Control::get_constant(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
+ if (p_type==StringName() || p_type=="") {
const int* constant = data.constant_override.getptr(p_name);
if (constant)
return *constant;
@@ -931,7 +934,7 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
while(theme_owner) {
if (theme_owner->data.theme->has_constant(p_name, type ) )
- return data.theme_owner->data.theme->get_constant(p_name, type );
+ return theme_owner->data.theme->get_constant(p_name, type );
Control *parent = theme_owner->get_parent()?theme_owner->get_parent()->cast_to<Control>():NULL;
if (parent)
@@ -946,12 +949,64 @@ int Control::get_constant(const StringName& p_name,const StringName& p_type) con
}
+bool Control::has_icon_override(const StringName& p_name) const {
+
+ const Ref<Texture>* tex = data.icon_override.getptr(p_name);
+ if (tex)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_shader_override(const StringName &p_name) const {
+
+ const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
+ if (sdr)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_stylebox_override(const StringName& p_name) const {
+
+ const Ref<StyleBox>* style = data.style_override.getptr(p_name);
+ if (style)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_font_override(const StringName& p_name) const {
+
+ const Ref<Font>* font = data.font_override.getptr(p_name);
+ if (font)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_color_override(const StringName& p_name) const {
+
+ const Color* color = data.color_override.getptr(p_name);
+ if (color)
+ return true;
+ else
+ return false;
+}
+
+bool Control::has_constant_override(const StringName& p_name) const {
+
+ const int* constant = data.constant_override.getptr(p_name);
+ if (constant)
+ return true;
+ else
+ return false;
+}
bool Control::has_icon(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Ref<Texture>* tex = data.icon_override.getptr(p_name);
- if (tex)
+ if (p_type==StringName() || p_type=="") {
+ if (has_icon_override(p_name) == true)
return true;
}
@@ -977,11 +1032,10 @@ bool Control::has_icon(const StringName& p_name,const StringName& p_type) const
}
-bool Control::has_shader(const StringName &p_name, const StringName &p_type) const
-{
- if (p_type==StringName()) {
- const Ref<Shader>* sdr = data.shader_override.getptr(p_name);
- if (sdr)
+bool Control::has_shader(const StringName &p_name, const StringName &p_type) const {
+
+ if (p_type==StringName() || p_type=="") {
+ if (has_shader_override(p_name)==true)
return true;
}
@@ -1008,10 +1062,8 @@ bool Control::has_shader(const StringName &p_name, const StringName &p_type) con
}
bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Ref<StyleBox>* style = data.style_override.getptr(p_name);
-
- if (style)
+ if (p_type==StringName() || p_type=="") {
+ if (has_stylebox_override(p_name)==true)
return true;
}
@@ -1038,9 +1090,8 @@ bool Control::has_stylebox(const StringName& p_name,const StringName& p_type) co
}
bool Control::has_font(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Ref<Font>* font = data.font_override.getptr(p_name);
- if (font)
+ if (p_type==StringName() || p_type=="") {
+ if (has_font_override(p_name)==true)
return true;
}
@@ -1066,11 +1117,11 @@ bool Control::has_font(const StringName& p_name,const StringName& p_type) const
return Theme::get_default()->has_font( p_name, type );
}
-bool Control::has_color(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
- const Color* color = data.color_override.getptr(p_name);
- if (color)
+bool Control::has_color(const StringName& p_name, const StringName& p_type) const {
+
+ if (p_type==StringName() || p_type=="") {
+ if (has_color_override(p_name)==true)
return true;
}
@@ -1098,10 +1149,8 @@ bool Control::has_color(const StringName& p_name,const StringName& p_type) const
bool Control::has_constant(const StringName& p_name,const StringName& p_type) const {
- if (p_type==StringName()) {
-
- const int* constant = data.constant_override.getptr(p_name);
- if (constant)
+ if (p_type==StringName() || p_type=="") {
+ if (has_constant_override(p_name) == true)
return true;
}
@@ -1505,7 +1554,15 @@ void Control::add_style_override(const StringName& p_name, const Ref<StyleBox>&
void Control::add_font_override(const StringName& p_name, const Ref<Font>& p_font) {
ERR_FAIL_COND(p_font.is_null());
+ if (data.font_override.has(p_name)) {
+ _unref_font(data.font_override[p_name]);
+ }
data.font_override[p_name]=p_font;
+
+ if (p_font.is_valid()) {
+ _ref_font(p_font);
+ }
+
notification(NOTIFICATION_THEME_CHANGED);
update();
}
@@ -1794,34 +1851,46 @@ void Control::_modal_stack_remove() {
}
-void Control::_propagate_theme_changed(Control *p_owner) {
+void Control::_propagate_theme_changed(CanvasItem *p_at,Control *p_owner) {
- for(int i=0;i<get_child_count();i++) {
+ 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++) {
+
+ 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) {
+
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);
}
}
@@ -2186,6 +2255,33 @@ float Control::_get_rotation_deg() const {
WARN_PRINT("Deprecated method Control._get_rotation_deg(): This method was renamed to get_rotation_deg. Please adapt your code accordingly, as the old method will be obsoleted.");
return get_rotation_deg();
}
+//needed to update the control if the font changes..
+void Control::_ref_font( Ref<Font> p_sc) {
+
+ if (!data.font_refcount.has(p_sc)) {
+ data.font_refcount[p_sc]=1;
+ p_sc->connect("changed",this,"_font_changed");
+ } else {
+ data.font_refcount[p_sc]+=1;
+ }
+}
+
+void Control::_unref_font(Ref<Font> p_sc) {
+
+ ERR_FAIL_COND(!data.font_refcount.has(p_sc));
+ data.font_refcount[p_sc]--;
+ if (data.font_refcount[p_sc]==0) {
+ p_sc->disconnect("changed",this,"_font_changed");
+ data.font_refcount.erase(p_sc);
+ }
+}
+
+void Control::_font_changed(){
+
+ update();
+ notification(NOTIFICATION_THEME_CHANGED);
+ minimum_size_changed(); //fonts affect minimum size pretty much almost always
+}
void Control::set_scale(const Vector2& p_scale){
@@ -2265,6 +2361,7 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_area_as_parent_rect","margin"),&Control::set_area_as_parent_rect,DEFVAL(0));
ObjectTypeDB::bind_method(_MD("show_modal","exclusive"),&Control::show_modal,DEFVAL(false));
ObjectTypeDB::bind_method(_MD("set_focus_mode","mode"),&Control::set_focus_mode);
+ ObjectTypeDB::bind_method(_MD("get_focus_mode"),&Control::get_focus_mode);
ObjectTypeDB::bind_method(_MD("has_focus"),&Control::has_focus);
ObjectTypeDB::bind_method(_MD("grab_focus"),&Control::grab_focus);
ObjectTypeDB::bind_method(_MD("release_focus"),&Control::release_focus);
@@ -2295,6 +2392,17 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("get_color","name","type"),&Control::get_color,DEFVAL(""));
ObjectTypeDB::bind_method(_MD("get_constant","name","type"),&Control::get_constant,DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_icon_override", "name"), &Control::has_icon_override);
+ ObjectTypeDB::bind_method(_MD("has_stylebox_override", "name"), &Control::has_stylebox_override);
+ ObjectTypeDB::bind_method(_MD("has_font_override", "name"), &Control::has_font_override);
+ ObjectTypeDB::bind_method(_MD("has_color_override", "name"), &Control::has_color_override);
+ ObjectTypeDB::bind_method(_MD("has_constant_override", "name"), &Control::has_constant_override);
+
+ ObjectTypeDB::bind_method(_MD("has_icon", "name", "type"), &Control::has_icon, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_stylebox", "name", "type"), &Control::has_stylebox, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_font", "name", "type"), &Control::has_font, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_color", "name", "type"), &Control::has_color, DEFVAL(""));
+ ObjectTypeDB::bind_method(_MD("has_constant", "name", "type"), &Control::has_constant, DEFVAL(""));
ObjectTypeDB::bind_method(_MD("get_parent_control:Control"),&Control::get_parent_control);
@@ -2324,6 +2432,9 @@ void Control::_bind_methods() {
ObjectTypeDB::bind_method(_MD("warp_mouse","to_pos"),&Control::warp_mouse);
+ ObjectTypeDB::bind_method(_MD("minimum_size_changed"), &Control::minimum_size_changed);
+
+ ObjectTypeDB::bind_method(_MD("_font_changed"), &Control::_font_changed);
BIND_VMETHOD(MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event")));
BIND_VMETHOD(MethodInfo(Variant::VECTOR2,"get_minimum_size"));