/usr/lib/ruby/vendor_ruby/ctioga2/graphics/styles/base.rb is in ctioga2 0.10-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 | # base.rb: the base of style objects
# copyright (c) 2009, 2012 by Vincent Fourmond
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details (in the COPYING file).
require 'ctioga2/log'
# This module contains all the classes used by ctioga
module CTioga2
module Graphics
# All the styles
module Styles
# 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.
class BasicStyle
OldAttrAccessor = method(:attr_accessor)
AllStyles = []
def self.inherited(cls)
AllStyles << cls
end
# This redefinition of attr_accessor allows to track for the
# names of the attributes, while still showing them up
# properly documented in rdoc.
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 list of attributes.
def self.attributes
return ( @attributes || [] ) +
if superclass.respond_to?(:attributes)
superclass.attributes
else
[]
end
end
# Returns the type of all attributes (chaining to the parent
# when applicable)
def self.attribute_types
return ( @attribute_types || {} ).
merge(
if superclass.respond_to?(:attribute_types)
superclass.attribute_types
else
{}
end
)
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.
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
# Define an attribute to be the alias for something else.
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
# Returns the type of an attribute, or _nil_ if there is no
# attribute of that name. Handles sub-styles correctly.
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
# Adds a deprecated typed attribute
def self.deprecated_attribute(symbol, type, message = true)
type = self.typed_attribute(symbol, type)
type.option_deprecated = message
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.
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
# Returns a hash suitable for using as an options hash.
#
# _key_ provides tuning of the key names.
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
def self.sub_styles
return @sub_styles
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)
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
# Creates a new object from a hash specification, just as in
# #set_from_hash.
def self.from_hash(hash, name = "%s")
obj = self.new
obj.set_from_hash(hash, name)
return obj
end
# We define instance_variable_defined? if Ruby does not have
# it... Old Ruby 1.8 versions don't - that is the case for
# those on MacOS.
if not self.respond_to?(:instance_variable_defined?)
def instance_variable_defined?(iv)
a = instance_variables.index(iv)
if a && a >= 0
return true
else
return false
end
end
end
# Converts to a hash. Does the reverse of #set_from_hash.
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
# Updates information from another object.
def update_from_other(other_object)
set_from_hash(other_object.to_hash)
end
end
end
end
end
|