diff options
Diffstat (limited to 'scene/gui/control.cpp')
-rw-r--r-- | scene/gui/control.cpp | 253 |
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")); |