diff options
Diffstat (limited to 'scene/resources/theme.cpp')
-rw-r--r-- | scene/resources/theme.cpp | 973 |
1 files changed, 973 insertions, 0 deletions
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp new file mode 100644 index 0000000000..c711bf5af1 --- /dev/null +++ b/scene/resources/theme.cpp @@ -0,0 +1,973 @@ +/*************************************************************************/ +/* theme.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* http://www.godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ +#include "theme.h" +#include "print_string.h" +#include "os/file_access.h" + + +Ref<Theme> Theme::default_theme; + + +bool Theme::_set(const StringName& p_name, const Variant& p_value) { + + String sname=p_name; + + if (sname.find("/")!=-1) { + + String type=sname.get_slice("/",1); + String node_type=sname.get_slice("/",0); + String name=sname.get_slice("/",2); + + if (type=="icons") { + + set_icon(name,node_type,p_value); + } else if (type=="styles") { + + set_stylebox(name,node_type,p_value); + } else if (type=="fonts") { + + set_font(name,node_type,p_value); + } else if (type=="colors") { + + set_color(name,node_type,p_value); + } else if (type=="constants") { + + set_constant(name,node_type,p_value); + } else + return false; + + return true; + } + + return false; + +} + +bool Theme::_get(const StringName& p_name,Variant &r_ret) const { + + String sname=p_name; + + if (sname.find("/")!=-1) { + + String type=sname.get_slice("/",1); + String node_type=sname.get_slice("/",0); + String name=sname.get_slice("/",2); + + if (type=="icons") { + + r_ret= get_icon(name,node_type); + } else if (type=="styles") { + + r_ret= get_stylebox(name,node_type); + } else if (type=="fonts") { + + r_ret= get_font(name,node_type); + } else if (type=="colors") { + + r_ret= get_color(name,node_type); + } else if (type=="constants") { + + r_ret= get_constant(name,node_type); + } else + return false; + + return true; + } + + return false; +} + +void Theme::_get_property_list( List<PropertyInfo> *p_list) const { + + const StringName *key=NULL; + + while((key=icon_map.next(key))) { + + const StringName *key2=NULL; + + while((key2=icon_map[*key].next(key2))) { + + p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) ); + } + } + + key=NULL; + + while((key=style_map.next(key))) { + + const StringName *key2=NULL; + + while((key2=style_map[*key].next(key2))) { + + p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) ); + } + } + + key=NULL; + + while((key=font_map.next(key))) { + + const StringName *key2=NULL; + + while((key2=font_map[*key].next(key2))) { + + p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) ); + } + } + + key=NULL; + + while((key=color_map.next(key))) { + + const StringName *key2=NULL; + + while((key2=color_map[*key].next(key2))) { + + p_list->push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) ); + } + } + + key=NULL; + + while((key=constant_map.next(key))) { + + const StringName *key2=NULL; + + while((key2=constant_map[*key].next(key2))) { + + p_list->push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) ); + } + } + +} + +Ref<Theme> Theme::get_default() { + + return default_theme; +} + +void Theme::set_default(const Ref<Theme>& p_default) { + + default_theme=p_default; +} + +Ref<Texture> Theme::default_icon; +Ref<StyleBox> Theme::default_style; +Ref<Font> Theme::default_font; + + +void Theme::set_default_icon( const Ref<Texture>& p_icon ) { + + default_icon=p_icon; +} +void Theme::set_default_style( const Ref<StyleBox>& p_style) { + + default_style=p_style; +} +void Theme::set_default_font( const Ref<Font>& p_font ) { + + default_font=p_font; +} + +void Theme::set_icon(const StringName& p_name,const StringName& p_type,const Ref<Texture>& p_icon) { + + ERR_FAIL_COND(p_icon.is_null()); + + bool new_value=!icon_map.has(p_type) || !icon_map[p_type].has(p_name); + + icon_map[p_type][p_name]=p_icon; + + if (new_value) + _change_notify(); +} +Ref<Texture> Theme::get_icon(const StringName& p_name,const StringName& p_type) const { + + if (icon_map.has(p_type) && icon_map[p_type].has(p_name) && icon_map[p_type][p_name].is_valid()) { + + return icon_map[p_type][p_name]; + } else { + return default_icon; + } +} + +bool Theme::has_icon(const StringName& p_name,const StringName& p_type) const { + + return (icon_map.has(p_type) && icon_map[p_type].has(p_name)); +} + + +void Theme::clear_icon(const StringName& p_name,const StringName& p_type) { + + ERR_FAIL_COND(!icon_map.has(p_type)); + ERR_FAIL_COND(!icon_map[p_type].has(p_name)); + + icon_map[p_type].erase(p_name); + _change_notify(); +} + +void Theme::get_icon_list(StringName p_type, List<StringName> *p_list) const { + + if (!icon_map.has(p_type)) + return; + + const StringName *key=NULL; + + while((key=icon_map[p_type].next(key))) { + + p_list->push_back(*key); + } + +} + + +void Theme::set_stylebox(const StringName& p_name,const StringName& p_type,const Ref<StyleBox>& p_style) { + + ERR_FAIL_COND(p_style.is_null()); + + bool new_value=!style_map.has(p_type) || !style_map[p_type].has(p_name); + + style_map[p_type][p_name]=p_style; + + if (new_value) + _change_notify(); +} + + +Ref<StyleBox> Theme::get_stylebox(const StringName& p_name,const StringName& p_type) const { + + if (style_map.has(p_type) && style_map[p_type].has(p_name) && style_map[p_type][p_name].is_valid()) { + + return style_map[p_type][p_name]; + } else { + return default_style; + } +} + +bool Theme::has_stylebox(const StringName& p_name,const StringName& p_type) const { + + return (style_map.has(p_type) && style_map[p_type].has(p_name) ); +} + +void Theme::clear_stylebox(const StringName& p_name,const StringName& p_type) { + + ERR_FAIL_COND(!style_map.has(p_type)); + ERR_FAIL_COND(!style_map[p_type].has(p_name)); + + style_map[p_type].erase(p_name); + _change_notify(); +} + +void Theme::get_stylebox_list(StringName p_type, List<StringName> *p_list) const { + + if (!style_map.has(p_type)) + return; + + const StringName *key=NULL; + + while((key=style_map[p_type].next(key))) { + + p_list->push_back(*key); + } + +} + +void Theme::set_font(const StringName& p_name,const StringName& p_type,const Ref<Font>& p_font) { + + ERR_FAIL_COND(p_font.is_null()); + + bool new_value=!font_map.has(p_type) || !font_map[p_type].has(p_name); + font_map[p_type][p_name]=p_font; + + if (new_value) + _change_notify(); +} +Ref<Font> Theme::get_font(const StringName& p_name,const StringName& p_type) const { + + if (font_map.has(p_type) && font_map[p_type].has(p_name) && font_map[p_type][p_name].is_valid()) + return font_map[p_type][p_name]; + else + return default_font; + +} + +bool Theme::has_font(const StringName& p_name,const StringName& p_type) const { + + return (font_map.has(p_type) && font_map[p_type].has(p_name)); +} + +void Theme::clear_font(const StringName& p_name,const StringName& p_type) { + + ERR_FAIL_COND(!font_map.has(p_type)); + ERR_FAIL_COND(!font_map[p_type].has(p_name)); + + font_map[p_type].erase(p_name); + _change_notify(); +} + +void Theme::get_font_list(StringName p_type, List<StringName> *p_list) const { + + if (!font_map.has(p_type)) + return; + + const StringName *key=NULL; + + while((key=font_map[p_type].next(key))) { + + p_list->push_back(*key); + } + +} + +void Theme::set_color(const StringName& p_name,const StringName& p_type,const Color& p_color) { + + bool new_value=!color_map.has(p_type) || !color_map[p_type].has(p_name); + + color_map[p_type][p_name]=p_color; + + if (new_value) + _change_notify(); +} + + + +Color Theme::get_color(const StringName& p_name,const StringName& p_type) const { + + if (color_map.has(p_type) && color_map[p_type].has(p_name)) + return color_map[p_type][p_name]; + else + return Color(); + +} + +bool Theme::has_color(const StringName& p_name,const StringName& p_type) const { + + return (color_map.has(p_type) && color_map[p_type].has(p_name)); +} + +void Theme::clear_color(const StringName& p_name,const StringName& p_type) { + + ERR_FAIL_COND(!color_map.has(p_type)); + ERR_FAIL_COND(!color_map[p_type].has(p_name)); + + color_map[p_type].erase(p_name); + _change_notify(); +} + +void Theme::get_color_list(StringName p_type, List<StringName> *p_list) const { + + if (!color_map.has(p_type)) + return; + + const StringName *key=NULL; + + while((key=color_map[p_type].next(key))) { + + p_list->push_back(*key); + } + +} + +void Theme::set_constant(const StringName& p_name,const StringName& p_type,int p_constant) { + + bool new_value=!constant_map.has(p_type) || !constant_map[p_type].has(p_name); + constant_map[p_type][p_name]=p_constant; + + if (new_value) + _change_notify(); +} + +int Theme::get_constant(const StringName& p_name,const StringName& p_type) const { + + if (constant_map.has(p_type) && constant_map[p_type].has(p_name)) + return constant_map[p_type][p_name]; + else { + return 0; + } + +} + +bool Theme::has_constant(const StringName& p_name,const StringName& p_type) const { + + return (constant_map.has(p_type) && constant_map[p_type].has(p_name)); +} + +void Theme::clear_constant(const StringName& p_name,const StringName& p_type) { + + ERR_FAIL_COND(!constant_map.has(p_type)); + ERR_FAIL_COND(!constant_map[p_type].has(p_name)); + + constant_map[p_type].erase(p_name); + _change_notify(); +} + +void Theme::get_constant_list(StringName p_type, List<StringName> *p_list) const { + + if (!constant_map.has(p_type)) + return; + + const StringName *key=NULL; + + while((key=constant_map[p_type].next(key))) { + + p_list->push_back(*key); + } + +} + + +void Theme::copy_default_theme() { + + Ref<Theme> default_theme=get_default(); + + icon_map=default_theme->icon_map; + style_map=default_theme->style_map; + font_map=default_theme->font_map; + color_map=default_theme->color_map; + constant_map=default_theme->constant_map; + _change_notify(); +} + +void Theme::get_type_list(List<StringName> *p_list) const { + + Set<StringName> types; + + const StringName *key=NULL; + + while((key=icon_map.next(key))) { + + types.insert(*key); + } + + key=NULL; + + while((key=style_map.next(key))) { + + types.insert(*key); + } + + key=NULL; + + while((key=font_map.next(key))) { + + types.insert(*key); + } + + key=NULL; + + while((key=color_map.next(key))) { + + types.insert(*key); + } + + key=NULL; + + while((key=constant_map.next(key))) { + + types.insert(*key); + } + + + for(Set<StringName>::Element *E=types.front();E;E=E->next()) { + + p_list->push_back(E->get()); + } +} + + +void Theme::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_icon","name","type","texture:Texture"),&Theme::set_icon); + ObjectTypeDB::bind_method(_MD("get_icon:Texture","name","type"),&Theme::get_icon); + ObjectTypeDB::bind_method(_MD("has_icon","name","type"),&Theme::has_icon); + ObjectTypeDB::bind_method(_MD("clear_icon","name","type"),&Theme::clear_icon); + ObjectTypeDB::bind_method(_MD("get_icon_list"),&Theme::_get_icon_list); + + ObjectTypeDB::bind_method(_MD("set_stylebox","name","type","texture:StyleBox"),&Theme::set_stylebox); + ObjectTypeDB::bind_method(_MD("get_stylebox:StyleBox","name","type"),&Theme::get_stylebox); + ObjectTypeDB::bind_method(_MD("has_stylebox","name","type"),&Theme::has_stylebox); + ObjectTypeDB::bind_method(_MD("clear_stylebox","name","type"),&Theme::clear_stylebox); + ObjectTypeDB::bind_method(_MD("get_stylebox_list"),&Theme::_get_stylebox_list); + + ObjectTypeDB::bind_method(_MD("set_font","name","type","font:Font"),&Theme::set_font); + ObjectTypeDB::bind_method(_MD("get_font:Font","name","type"),&Theme::get_font); + ObjectTypeDB::bind_method(_MD("has_font","name","type"),&Theme::has_font); + ObjectTypeDB::bind_method(_MD("clear_font","name","type"),&Theme::clear_font); + ObjectTypeDB::bind_method(_MD("get_font_list"),&Theme::_get_font_list); + + ObjectTypeDB::bind_method(_MD("set_color","name","type","color"),&Theme::set_color); + ObjectTypeDB::bind_method(_MD("get_color","name","type"),&Theme::get_color); + ObjectTypeDB::bind_method(_MD("has_color","name","type"),&Theme::has_color); + ObjectTypeDB::bind_method(_MD("clear_color","name","type"),&Theme::clear_color); + ObjectTypeDB::bind_method(_MD("get_color_list"),&Theme::_get_color_list); + + ObjectTypeDB::bind_method(_MD("set_constant","name","type","constant"),&Theme::set_constant); + ObjectTypeDB::bind_method(_MD("get_constant","name","type"),&Theme::get_constant); + ObjectTypeDB::bind_method(_MD("has_constant","name","type"),&Theme::has_constant); + ObjectTypeDB::bind_method(_MD("clear_constant","name","type"),&Theme::clear_constant); + ObjectTypeDB::bind_method(_MD("get_constant_list"),&Theme::_get_constant_list); + + ObjectTypeDB::bind_method(_MD("get_type_list"),&Theme::_get_type_list); + + ObjectTypeDB::bind_method("copy_default_theme",&Theme::copy_default_theme); + +} + +Theme::Theme() { + + +} + + +Theme::~Theme() +{ +} + + + +RES ResourceFormatLoaderTheme::load(const String &p_path,const String& p_original_path) { + + Error err; + FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); + + ERR_EXPLAIN("Unable to open theme file: "+p_path); + ERR_FAIL_COND_V(err,RES()); + String base_path = p_path.get_base_dir(); + Ref<Theme> theme( memnew( Theme ) ); + Map<StringName,Variant> library; + + bool reading_library=false; + int line=0; + + while(!f->eof_reached()) { + + String l = f->get_line().strip_edges(); + line++; + + int comment = l.find(";"); + if (comment!=-1) + l=l.substr(0,comment); + if (l=="") + continue; + + if (l.begins_with("[")) { + if (l=="[library]") { + reading_library=true; + } else if (l=="[theme]") { + reading_library=false; + } else { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Unknown section type: '"+l+"'."); + ERR_FAIL_V(RES()); + } + continue; + } + + int eqpos = l.find("="); + if (eqpos==-1) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Expected '='."); + ERR_FAIL_V(RES()); + } + + + String right=l.substr(eqpos+1,l.length()).strip_edges(); + if (right=="") { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Expected value after '='."); + ERR_FAIL_V(RES()); + } + + Variant value; + + if (right.is_valid_integer()) { + //is number + value = right.to_int(); + } else if (right.is_valid_html_color()) { + //is html color + value = Color::html(right); + } else if (right.begins_with("@")) { //reference + + String reference = right.substr(1,right.length()); + if (!library.has(reference)) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid reference to '"+reference+"'."); + ERR_FAIL_V(RES()); + + } + + value=library[reference]; + + } else if (right.begins_with("default")) { //use default + //do none + } else { + //attempt to parse a constructor + int popenpos = right.find("("); + + if (popenpos==-1) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor syntax: "+right); + ERR_FAIL_V(RES()); + } + + int pclosepos = right.find_last(")"); + + if (pclosepos==-1) { + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor parameter syntax: "+right); + ERR_FAIL_V(RES()); + + } + + String type = right.substr(0,popenpos); + String param = right.substr(popenpos+1,pclosepos-popenpos-1); + + + + if (type=="icon") { + + String path; + + if (param.is_abs_path()) + path=param; + else + path=base_path+"/"+param; + + Ref<Texture> texture = ResourceLoader::load(path); + if (!texture.is_valid()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't find icon at path: "+path); + ERR_FAIL_V(RES()); + } + + value=texture; + + } else if (type=="sbox") { + + String path; + + if (param.is_abs_path()) + path=param; + else + path=base_path+"/"+param; + + Ref<StyleBox> stylebox = ResourceLoader::load(path); + if (!stylebox.is_valid()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't find stylebox at path: "+path); + ERR_FAIL_V(RES()); + } + + value=stylebox; + + } else if (type=="sboxt") { + + Vector<String> params = param.split(","); + if (params.size()!=5 && params.size()!=9) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for sboxt(): '"+right+"'."); + ERR_FAIL_V(RES()); + + } + + String path=params[0]; + + if (!param.is_abs_path()) + path=base_path+"/"+path; + + Ref<Texture> tex = ResourceLoader::load(path); + if (tex.is_null()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Could not open texture for sboxt at path: '"+params[0]+"'."); + ERR_FAIL_V(RES()); + + } + + Ref<StyleBoxTexture> sbtex( memnew(StyleBoxTexture) ); + + sbtex->set_texture(tex); + + for(int i=0;i<4;i++) { + if (!params[i+1].is_valid_integer()) { + + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid expand margin parameter for sboxt #"+itos(i+1) +", expected integer constant, got: '"+params[i+1]+"'."); + ERR_FAIL_V(RES()); + } + + int margin = params[i+1].to_int(); + sbtex->set_expand_margin_size(Margin(i),margin); + } + + if (params.size()==9) { + + for(int i=0;i<4;i++) { + + if (!params[i+5].is_valid_integer()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid expand margin parameter for sboxt #"+itos(i+5) +", expected integer constant, got: '"+params[i+5]+"'."); + ERR_FAIL_V(RES()); + } + + int margin = params[i+5].to_int(); + sbtex->set_margin_size(Margin(i),margin); + } + } + + value = sbtex; + } else if (type=="sboxf") { + + Vector<String> params = param.split(","); + if (params.size()<2) { + + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for sboxf(): '"+right+"'."); + ERR_FAIL_V(RES()); + + } + + Ref<StyleBoxFlat> sbflat( memnew(StyleBoxFlat) ); + + if (!params[0].is_valid_integer()) { + + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Expected integer numeric constant for parameter 0 (border size)."); + ERR_FAIL_V(RES()); + + } + + sbflat->set_border_size(params[0].to_int()); + + if (!params[0].is_valid_integer()) { + + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Expected integer numeric constant for parameter 0 (border size)."); + ERR_FAIL_V(RES()); + + } + + + int left = MIN( params.size()-1, 3 ); + + int ccodes=0; + + for(int i=0;i<left;i++) { + + if (params[i+1].is_valid_html_color()) + ccodes++; + else + break; + } + + Color normal; + Color bright; + Color dark; + + if (ccodes<1) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Expected at least 1, 2 or 3 html color codes."); + ERR_FAIL_V(RES()); + } else if (ccodes==1) { + + normal=Color::html(params[1]); + bright=Color::html(params[1]); + dark=Color::html(params[1]); + } else if (ccodes==2) { + + normal=Color::html(params[1]); + bright=Color::html(params[2]); + dark=Color::html(params[2]); + } else { + + normal=Color::html(params[1]); + bright=Color::html(params[2]); + dark=Color::html(params[3]); + } + + sbflat->set_dark_color(dark); + sbflat->set_light_color(bright); + sbflat->set_bg_color(normal); + + if (params.size()==ccodes+5) { + //margins + for(int i=0;i<4;i++) { + + if (!params[i+ccodes+1].is_valid_integer()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid expand margin parameter for sboxf #"+itos(i+ccodes+1) +", expected integer constant, got: '"+params[i+ccodes+1]+"'."); + ERR_FAIL_V(RES()); + } + +// int margin = params[i+ccodes+1].to_int(); + //sbflat->set_margin_size(Margin(i),margin); + } + } else if (params.size()!=ccodes+1) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid amount of margin parameters for sboxt."); + ERR_FAIL_V(RES()); + + } + + + value=sbflat; + + } else { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor type: '"+type+"'."); + ERR_FAIL_V(RES()); + + } + + } + + + //parse left and do something with it + String left= l.substr(0,eqpos); + + if (reading_library) { + + left=left.strip_edges(); + if (!left.is_valid_identifier()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": <LibraryItem> is not a valid identifier."); + ERR_FAIL_V(RES()); + } + if (library.has(left)) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Already in library: '"+left+"'."); + ERR_FAIL_V(RES()); + } + + library[left]=value; + } else { + + int pointpos = left.find("."); + if (pointpos==-1) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Expected 'control.item=..' assign syntax."); + ERR_FAIL_V(RES()); + } + + String control=left.substr(0,pointpos).strip_edges(); + if (!control.is_valid_identifier()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": <Control> is not a valid identifier."); + ERR_FAIL_V(RES()); + } + String item=left.substr(pointpos+1,left.size()).strip_edges(); + if (!item.is_valid_identifier()) { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": <Item> is not a valid identifier."); + ERR_FAIL_V(RES()); + } + + if (value.get_type()==Variant::NIL) { + //try to use exiting + if (Theme::get_default()->has_stylebox(item,control)) + value=Theme::get_default()->get_stylebox(item,control); + else if (Theme::get_default()->has_font(item,control)) + value=Theme::get_default()->get_font(item,control); + else if (Theme::get_default()->has_icon(item,control)) + value=Theme::get_default()->get_icon(item,control); + else if (Theme::get_default()->has_color(item,control)) + value=Theme::get_default()->get_color(item,control); + else if (Theme::get_default()->has_constant(item,control)) + value=Theme::get_default()->get_constant(item,control); + else { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Default not present for: '"+control+"."+item+"'."); + ERR_FAIL_V(RES()); + } + + } + + if (value.get_type()==Variant::OBJECT) { + + Ref<Resource> res = value; + if (!res.is_valid()) { + + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid resource (NULL)."); + ERR_FAIL_V(RES()); + } + + if (res->cast_to<StyleBox>()) { + + theme->set_stylebox(item,control,res); + } else if (res->cast_to<Font>()) { + theme->set_font(item,control,res); + } else if (res->cast_to<Font>()) { + theme->set_font(item,control,res); + } else if (res->cast_to<Texture>()) { + theme->set_icon(item,control,res); + } else { + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid resource type."); + ERR_FAIL_V(RES()); + } + } else if (value.get_type()==Variant::COLOR) { + + theme->set_color(item,control,value); + + } else if (value.get_type()==Variant::INT) { + + theme->set_constant(item,control,value); + + } else { + + memdelete(f); + ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't even determine what this setting is! what did you do!?"); + ERR_FAIL_V(RES()); + } + + } + + + } + + f->close(); + memdelete(f); + + return theme; +} + +void ResourceFormatLoaderTheme::get_recognized_extensions(List<String> *p_extensions) const { + + p_extensions->push_back("theme"); +} + +bool ResourceFormatLoaderTheme::handles_type(const String& p_type) const { + + return p_type=="Theme"; +} + +String ResourceFormatLoaderTheme::get_resource_type(const String &p_path) const { + + if (p_path.extension().to_lower()=="theme") + return "Theme"; + return ""; +} |