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

alias_for(what, target, define_methods = false) click to toggle source

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
aliases() click to toggle source

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
attr_accessor(symbol) click to toggle source

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
attribute_type(symbol, fmt = "%s") click to toggle source

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
attribute_types() click to toggle source

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
attributes() click to toggle source

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
convert_string_hash(opts, key = "%s") click to toggle source

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
defined_aliases() click to toggle source
# File lib/ctioga2/graphics/styles/base.rb, line 100
def self.defined_aliases
  return @aliases || {}
end
deprecated_attribute(symbol, type, message = true) click to toggle source

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
from_hash(hash, name = "%s") click to toggle source

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
inherited(cls) click to toggle source
# File lib/ctioga2/graphics/styles/base.rb, line 73
def self.inherited(cls)
  AllStyles << cls
end
normalize_hash(hsh, fmt = "%s") click to toggle source
# 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
normalize_in(name, fmt = "%s") click to toggle source
# 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
normalize_out(name) click to toggle source
# File lib/ctioga2/graphics/styles/base.rb, line 61
def self.normalize_out(name)
  return name.gsub('_', '-')
end
options_hash(key = "%s") click to toggle source

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
sub_style(symbol, cls, fmt = nil, force_create = false) click to toggle source

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
sub_styles() click to toggle source
# 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
typed_attribute(symbol, type) click to toggle source

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

instance_variable_defined?(iv) click to toggle source
# 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
set_from_hash(hash, name = "%s") click to toggle source

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
to_hash(name = "%s") click to toggle source

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
update_from_other(other_object) click to toggle source

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
use_defaults_from(hsh) click to toggle source

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