class CTioga2::Graphics::Styles::BasicStyle
This style is the base class of a series of style objects that share one common feature: all their attributes can be set using the set_from_hash
function.
Constants
- AllStyles
- OldAttrAccessor
Public Class Methods
Define an attribute to be the alias for something else.
@todo Maybe make multiple aliases ?
# File lib/ctioga2/graphics/styles/base.rb, line 141 def self.alias_for(what, target, define_methods = false) target = self.normalize_in(target) what = self.normalize_in(what) @aliases ||= {} @aliases[what] = target if define_methods alias_method what.to_sym, target.to_sym alias_method "#{what}=".to_sym, "#{target}=".to_sym end end
Returns the list of valid aliases, including those defined in parent classes.
# File lib/ctioga2/graphics/styles/base.rb, line 35 def self.aliases ret = if superclass.respond_to? :aliases superclass.aliases else {} end if @aliases ret.merge!(@aliases) end return ret end
This redefinition of attr_accessor
allows to track for the names of the attributes, while still showing them up properly documented in rdoc.
# File lib/ctioga2/graphics/styles/base.rb, line 80 def self.attr_accessor(symbol) cal = caller # if ! (caller[0] =~ /typed_attribute/) # puts "Deprecated use at #{caller[0]}" # end @attributes ||= [] @attributes << symbol OldAttrAccessor.call(symbol) end
Returns the type of an attribute, or nil if there is no attribute of that name. Handles sub-styles correctly.
# File lib/ctioga2/graphics/styles/base.rb, line 154 def self.attribute_type(symbol, fmt = "%s") name = self.normalize_in(symbol.to_s, fmt) for k,v in attribute_types if (fmt % k.to_s) == name if v.respond_to? :type return v.type else return v end end end if @sub_styles # Not always present too for sub in @sub_styles sym, cls, fmt2, fc = *sub f = fmt % fmt2 ret = cls.attribute_type(name, f) return ret if ret end end return nil end
Returns the type of all attributes (chaining to the parent when applicable)
# File lib/ctioga2/graphics/styles/base.rb, line 106 def self.attribute_types return ( @attribute_types || {} ). merge( if superclass.respond_to?(:attribute_types) superclass.attribute_types else {} end ) end
Returns the list of attributes.
# File lib/ctioga2/graphics/styles/base.rb, line 91 def self.attributes return ( @attributes || [] ) + if superclass.respond_to?(:attributes) superclass.attributes else [] end end
Converts a hash in text format into a format suitable for feeding to set_from_hash
. Only relevant keys are converted. Keys that exist in the options hash but are not Strings are left untouched
# File lib/ctioga2/graphics/styles/base.rb, line 379 def self.convert_string_hash(opts, key = "%s") cnv = self.options_hash(key) ret = {} for k,v in opts if cnv.key? k if v.is_a? String ret[k] = cnv[k].type.string_to_type(v) else ret[k] = v end end end return ret end
# File lib/ctioga2/graphics/styles/base.rb, line 100 def self.defined_aliases return @aliases || {} end
Adds a deprecated typed attribute
# File lib/ctioga2/graphics/styles/base.rb, line 179 def self.deprecated_attribute(symbol, type, message = true) type = self.typed_attribute(symbol, type) type.option_deprecated = message end
Creates a new object from a hash specification, just as in set_from_hash
.
# File lib/ctioga2/graphics/styles/base.rb, line 308 def self.from_hash(hash, name = "%s") obj = self.new obj.set_from_hash(hash, name) return obj end
# File lib/ctioga2/graphics/styles/base.rb, line 73 def self.inherited(cls) AllStyles << cls end
# File lib/ctioga2/graphics/styles/base.rb, line 65 def self.normalize_hash(hsh, fmt = "%s") ret = {} for k,v in hsh ret[normalize_in(k, fmt)] = v end return ret end
# File lib/ctioga2/graphics/styles/base.rb, line 47 def self.normalize_in(name, fmt = "%s") name = name.to_s.downcase.gsub('-', '_') als = self.aliases if als for k, v in als if fmt % k == name name = fmt % v break end end end return name end
# File lib/ctioga2/graphics/styles/base.rb, line 61 def self.normalize_out(name) return name.gsub('_', '-') end
Returns a hash suitable for using as an options hash.
key provides tuning of the key names.
# File lib/ctioga2/graphics/styles/base.rb, line 207 def self.options_hash(key = "%s") ret = if superclass.respond_to?(:options_hash) superclass.options_hash(key) else {} end if @attribute_types # Not always present for k, v in @attribute_types ret[key % k] = v end end if @sub_styles # Not always present too for sub in @sub_styles sym, cls, fmt, fc = *sub fmt = key % fmt ret.merge!(cls.options_hash(fmt)) end end # And now we expand options if @aliases for k, v in @aliases v = key % v if ret.key?(v) ret[key % k] = ret[v] end end end return ret end
Defines an accessor for an attribute which is a BasicStyle
subclass in itself.
fmt is the thing fed to the subclass for the from_hash function.
if force_create is on, then the corresponding sub-object is created even if no property we set within.
# File lib/ctioga2/graphics/styles/base.rb, line 192 def self.sub_style(symbol, cls, fmt = nil, force_create = false) @sub_styles ||= [] # A list of [symbol, cls, fmt] if ! fmt fmt = "#{symbol.to_s}_%s" end @sub_styles << [symbol, cls, fmt, force_create] # Define the accessor OldAttrAccessor.call(symbol) end
# File lib/ctioga2/graphics/styles/base.rb, line 241 def self.sub_styles # p [:ss, self] rv = if self.superclass.respond_to?(:sub_styles) self.superclass.sub_styles else [] end # p [:sparents, self, rv] if @sub_styles rv += @sub_styles end # p [:sparents_own, self, rv] return rv end
This function should be the main way now of declaring attributes, as it allows one to automatically generate an options hash for Command
@todo There may be a reason to make some of the attributes private to some extent ?
@todo Provide a function to make attributes “aliases” of others (but just on the hash side of the things), in order for instance to have halign and valign as aliases for the less intuitive alignment and justification.
# File lib/ctioga2/graphics/styles/base.rb, line 128 def self.typed_attribute(symbol, type) sym = symbol.to_sym self.attr_accessor(sym) # The unless type.respond_to? :string_to_type seems type = CmdArg.new(type) # unless type.respond_to? :string_to_type @attribute_types ||= {} @attribute_types[sym] = type return type end
Public Instance Methods
# File lib/ctioga2/graphics/styles/base.rb, line 318 def instance_variable_defined?(iv) a = instance_variables.index(iv) if a && a >= 0 return true else return false end end
Sets
the values of the attributes from the given hash. Keys are looked under the form of
name % key_name
where key_name takes all the values of the attributes.
Unspecified attributes are not removed from the object. Extra keys are silently ignored.
@todo Maybe there should be a way to detect extra attributes ?
This function returns the number of properties that were effectively set (including those set in sub-styles)
# File lib/ctioga2/graphics/styles/base.rb, line 270 def set_from_hash(hash, name = "%s") hash = self.class.normalize_hash(hash, name) nb_set = 0 for key_name in self.class.attributes hash_key = name % key_name if hash.key? hash_key self.send("#{key_name}=", hash[hash_key]) nb_set += 1 end end if self.class.sub_styles for sub in self.class.sub_styles sym, cls, fmt, fc = *sub cur_var = self.send(sym) if ! cur_var # Create if not present cur_var = cls.new set_after = true end # p :bef, fmt fmt = name % fmt # p :aft, fmt nb = cur_var.set_from_hash(hash, fmt) # Here, this means that missing attributes do not get # created. if (nb > 0 or fc) and set_after self.send("#{sym}=", cur_var) end nb_set += nb end end return nb_set end
Converts to a hash. Does the reverse of set_from_hash
.
nil values get stripped off (but not false values, of course).
# File lib/ctioga2/graphics/styles/base.rb, line 331 def to_hash(name = "%s") retval = {} for attr in self.class.attributes if instance_variable_defined?("@#{attr}") val = instance_variable_get("@#{attr}") if ! val.nil? retval[name % attr] = val end end end # Now, substyles for sb in self.class.sub_styles symb, cls, fmt, fc = *sb if instance_variable_defined?("@#{symb.to_s}") sub = instance_variable_get("@#{symb.to_s}") fmt = name % fmt if ! sub.nil? retval.update(sub.to_hash(fmt)) end end end return retval end
Updates information from another object.
# File lib/ctioga2/graphics/styles/base.rb, line 357 def update_from_other(other_object) set_from_hash(other_object.to_hash) end
Sets
the style from the given hash or other object, if the style is not present yet.
# File lib/ctioga2/graphics/styles/base.rb, line 363 def use_defaults_from(hsh) if hsh.is_a? BasicStyle hsh = hsh.to_hash end at = self.class.attribute_types for k, v in hsh if at.key?(k.to_sym) and ! instance_variable_defined?("@#{k}".to_sym) self.send("#{k}=", v) end end end