Class: CTioga2::Graphics::Styles::BasicStyle

Inherits:
Object
  • Object
show all
Defined in:
lib/ctioga2/graphics/styles/base.rb

Overview

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.

Constant Summary collapse

OldAttrAccessor =
method(:attr_accessor)
AllStyles =
[]

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.alias_for(symbol, target) ⇒ Object

Define an attribute to be the alias for something else.



94
95
96
97
98
99
100
101
102
103
104
# File 'lib/ctioga2/graphics/styles/base.rb', line 94

def self.alias_for(symbol, target)
  target = target.to_sym
  if ! @attribute_types[target]
    raise "Declaring alias #{symbol} for unexisting target #{target}"
  end
  symbol = symbol.to_sym
  @attribute_types[symbol] = @attribute_types[target]
  @attributes << symbol
  alias_method symbol, target
  alias_method "#{symbol}=".to_sym, "#{target}=".to_sym
end

.attr_accessor(symbol) ⇒ Object

This redefinition of attr_accessor allows to track for the names of the attributes, while still showing them up properly documented in rdoc.



40
41
42
43
44
45
46
47
48
# File 'lib/ctioga2/graphics/styles/base.rb', line 40

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") ⇒ Object

Returns the type of an attribute, or nil if there is no attribute of that name. Handles sub-styles correctly.



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/ctioga2/graphics/styles/base.rb', line 108

def self.attribute_type(symbol, fmt = "%s")
  name = symbol.to_s

  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(symbol, f)
      return ret if ret
    end
  end
  return nil
end

.attribute_typesObject

Returns the type of all attributes (chaining to the parent when applicable)



62
63
64
65
66
67
68
69
70
71
# File 'lib/ctioga2/graphics/styles/base.rb', line 62

def self.attribute_types
  return ( @attribute_types || {} ).
    merge(
          if superclass.respond_to?(:attribute_types)
            superclass.attribute_types
          else
            {}
          end
          )
end

.attributesObject

Returns the list of attributes.



51
52
53
54
55
56
57
58
# File 'lib/ctioga2/graphics/styles/base.rb', line 51

def self.attributes
  return ( @attributes || [] ) + 
    if superclass.respond_to?(:attributes)
      superclass.attributes
    else
      []
    end
end

.deprecated_attribute(symbol, type, message = true) ⇒ Object

Adds a deprecated typed attribute



133
134
135
136
# File 'lib/ctioga2/graphics/styles/base.rb', line 133

def self.deprecated_attribute(symbol, type, message = true)
  type = self.typed_attribute(symbol, type)
  type.option_deprecated = message
end

.from_hash(hash, name = "%s") ⇒ Object

Creates a new object from a hash specification, just as in #set_from_hash.



238
239
240
241
242
# File 'lib/ctioga2/graphics/styles/base.rb', line 238

def self.from_hash(hash, name = "%s")
  obj = self.new
  obj.set_from_hash(hash, name)
  return obj
end

.inherited(cls) ⇒ Object



33
34
35
# File 'lib/ctioga2/graphics/styles/base.rb', line 33

def self.inherited(cls)
  AllStyles << cls
end

.options_hash(key = "%s") ⇒ Object

Returns a hash suitable for using as an options hash.

key provides tuning of the key names.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/ctioga2/graphics/styles/base.rb', line 161

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

  return ret
end

.sub_style(symbol, cls, fmt = nil, force_create = false) ⇒ Object

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.



146
147
148
149
150
151
152
153
154
155
156
# File 'lib/ctioga2/graphics/styles/base.rb', line 146

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_stylesObject



185
186
187
# File 'lib/ctioga2/graphics/styles/base.rb', line 185

def self.sub_styles
  return @sub_styles
end

.typed_attribute(symbol, type) ⇒ Object

TODO:

There may be a reason to make some of the attributes

TODO:

Provide a function to make attributes “aliases” of

This function should be the main way now of declaring attributes, as it allows one to automatically generate an options hash for Command

private to some extent ?

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.



84
85
86
87
88
89
90
91
# File 'lib/ctioga2/graphics/styles/base.rb', line 84

def self.typed_attribute(symbol, type)
  sym = symbol.to_sym
  self.attr_accessor(sym)
  type = CmdArg.new(type) unless type.respond_to? :string_to_type
  @attribute_types ||= {}
  @attribute_types[sym] = type
  return type
end

Instance Method Details

#instance_variable_defined?(iv) ⇒ Boolean

Returns:

  • (Boolean)


248
249
250
251
252
253
254
255
# File 'lib/ctioga2/graphics/styles/base.rb', line 248

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") ⇒ Object

TODO:

Maybe there should be a way to detect extra attributes ?

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.

This function returns the number of properties that were effectively set (including those set in sub-styles)



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/ctioga2/graphics/styles/base.rb', line 203

def set_from_hash(hash, name = "%s")
  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
      fmt = name % 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") ⇒ Object

Converts to a hash. Does the reverse of #set_from_hash.



259
260
261
262
263
264
265
266
267
# File 'lib/ctioga2/graphics/styles/base.rb', line 259

def to_hash(name = "%s")
  retval = {}
  for attr in self.class.attributes
    if instance_variable_defined?("@#{attr}")
      retval[name % attr] = instance_variable_get("@#{attr}")
    end
  end
  return retval
end

#update_from_other(other_object) ⇒ Object

Updates information from another object.



270
271
272
# File 'lib/ctioga2/graphics/styles/base.rb', line 270

def update_from_other(other_object)
  set_from_hash(other_object.to_hash)
end