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

.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.



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ctioga2/graphics/styles/base.rb', line 95

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



120
121
122
123
# File 'lib/ctioga2/graphics/styles/base.rb', line 120

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.



225
226
227
228
229
# File 'lib/ctioga2/graphics/styles/base.rb', line 225

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.



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/ctioga2/graphics/styles/base.rb', line 148

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.



133
134
135
136
137
138
139
140
141
142
143
# File 'lib/ctioga2/graphics/styles/base.rb', line 133

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



172
173
174
# File 'lib/ctioga2/graphics/styles/base.rb', line 172

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)


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

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)



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/ctioga2/graphics/styles/base.rb', line 190

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.



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

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.



257
258
259
# File 'lib/ctioga2/graphics/styles/base.rb', line 257

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