class CTioga2::Graphics::Styles::CurveStyleFactory
This object is in charge of the generation of the CurveStyle
object for the next curve to be drawn.
Constants
- AutoRE
Switch some parameter back to automatic
- CurveStyleGroup
The CmdGroup for stylistic information about curves.
- DisableRE
Sets
some parameter to false.- LinkRE
If that matches, we use the value as a link to other values.
- PlotCommandOptions
A constant suitable for use as the optional arguments of the plot command.
Attributes
A hash containing values that override default ones derived from the CircularArray
objects.
A hash of CircularArray
objects.
Public Class Methods
Creates two commands for each parameter of the object:
-
a command to set the override
-
a command to choose the sets.
# File lib/ctioga2/graphics/styles/factory.rb, line 190 def self.create_commands parameters.each do |target, param| next if param.disable_commands override_cmd = Cmd.new("#{param.name}", param.short_option, "--#{param.name}", [ CmdArg.new("#{param.type.name}-or-auto") ], {}, "Sets the #{param.description} for subsequent curves", "Sets the #{param.description} for subsequent curves, until cancelled with @auto@ as argument.", CurveStyleGroup) do |plotmaker, value| plotmaker.curve_generator.style_factory. set_parameter_override(target, value) end if param.sets next if param.disable_commands set_cmd = Cmd.new("#{param.name}-set", nil, "--#{param.name}-set", [ CmdArg.new("#{param.type.name}-set") ], {}, "Chooses a set for the #{param.description} of subsequent curves", "Chooses a set for the #{param.description} of subsequent curves. Also sets {command: #{param.name}} to @auto@, so that the set takes effect immediately", CurveStyleGroup) do |plotmaker, value| plotmaker.curve_generator.style_factory. set_parameter_set(target, value) plotmaker.curve_generator.style_factory. set_parameter_override(target, 'auto') end end end end
Creates a new parameter for the style factory.
# File lib/ctioga2/graphics/styles/factory.rb, line 119 def self.define_parameter(target, name, sets, description, short_option = nil, disable_cmds = false) # We define two new types: # - first, the color-or-auto type: base_type = CurveStyle.attribute_type(target) if ! Commands::Interpreter.type("#{base_type.name}-or-auto") mb_type = base_type.type.dup mb_type.re_shortcuts = (mb_type.re_shortcuts ? mb_type.re_shortcuts.dup : {}) mb_type.re_shortcuts[AutoRE] = 'auto' mb_type.re_shortcuts[DisableRE] = false # Add passthrough for expressions such as =color... mb_type.passthrough = LinkRE # Now, register a type for the type or automatic. CmdType.new("#{base_type.name}-or-auto", mb_type, "Same thing as {type:#{base_type.name}}, or @auto@ to let the style factory handle automatically.") end if sets and ! Commands::Interpreter.type("#{base_type.name}-set") # Now, register a type for the type or automatic. CmdType.new("#{base_type.name}-set",{ :type => :set, :subtype => base_type.type, :shortcuts => sets } , "Sets of {type: #{base_type.name}}") end param = CurveStyleFactoryParameter.new(name, base_type, sets, description, short_option, disable_cmds) @parameters ||= {} @parameters[target] = param @name_to_target ||= {} @name_to_target[name] = target end
Returns the Hash
containing the class parameters.
# File lib/ctioga2/graphics/styles/factory.rb, line 176 def self.name_to_target return @name_to_target end
Creates a new CurveStyleFactory
.
# File lib/ctioga2/graphics/styles/factory.rb, line 254 def initialize # Overrides as in the first ctioga @override_parameters = { 'line_style' => LineStyles::Solid, 'marker' => false, 'marker_scale' => 0.5, 'fill_color' => '=color'.to_sym, 'error_bar_color' => '=marker_color'.to_sym } @parameters_carrays = {} for target, param in self.class.parameters # There should be a way to do that ! set = param.default_set if set @parameters_carrays[target] = CircularArray.new(set) end end @next_style = nil end
Returns the Hash
containing the class parameters.
# File lib/ctioga2/graphics/styles/factory.rb, line 170 def self.parameters return @parameters || {} end
This function returns a hash suitable for use with the plot command as optional arguments, that will end up as the one_time hash in next
.
# File lib/ctioga2/graphics/styles/factory.rb, line 230 def self.plot_optional_arguments args = {} for option_name, param in @parameters args[param.name] = CmdArg.new(param.type) end # Here, we add the support for a /legend= option args['legend'] = CmdArg.new('text') @name_to_target['legend'] = 'legend' return args end
A simple parameter is something whose target defines all, ie only the name and a documentation text is necessary.
# File lib/ctioga2/graphics/styles/factory.rb, line 164 def self.simple_parameter(target, text, sets = nil, short = nil) name = target.gsub(/_/, '-') define_parameter(target, name, sets, text, short) end
Public Instance Methods
Converts the one-time parameters, which is a hash whose keys are the names of the parameters to targets.
# File lib/ctioga2/graphics/styles/factory.rb, line 437 def hash_name_to_target(h) retval = {} convert = self.class.name_to_target for k,v in h if convert.key? k retval[convert[k]] = v else warn { "Unkown key for hash_name_to_target: #{k}" } end end return retval end
Gets the style for the next curve. The one_time hash contains values 'parameter name' (name, and not target) => value that are used for this time only.
# File lib/ctioga2/graphics/styles/factory.rb, line 284 def next(one_time = {}) if @next_style base = @next_style @next_style = nil else base = {} for target, array in @parameters_carrays base[target] = array.next end base.merge!(@override_parameters) end base.merge!(hash_name_to_target(one_time)) return CurveStyle.from_hash(resolve_links(base)) end
Sets
the override for the given parameter. This corresponds to fixing manually the corresponding element until the override is removed, by a call with a value that matches AutoRE
.
The value should ideally be a String
that is further converted to the appropriate type. Non-string objects will be left untouched.
# File lib/ctioga2/graphics/styles/factory.rb, line 309 def set_parameter_override(target, value) param = get_parameter(target) # Perform automatic type conversion only on strings. if value.is_a? String if value =~ AutoRE @override_parameters.delete(target) return elsif value =~ LinkRE t = $1 convert = self.class.name_to_target if convert.key?(t) value = "=#{convert[t]}".to_sym else warn { "No known key: #{t}, treating as auto" } @override_parameters.delete(target) return end elsif value =~ DisableRE value = false else value = param.type.string_to_type(value) end end @override_parameters[target] = value end
Sets
the CircularArray
set corresponding to the named
# File lib/ctioga2/graphics/styles/factory.rb, line 338 def set_parameter_set(target, value) param = get_parameter(target) # Perform automatic type conversion only on strings. if value.is_a? String value = param.sets_type.string_to_type(value) end @parameters_carrays[target].set = value end
Protected Instance Methods
Returns the CurveFactoryParameterType object corresponding to the named parameter.
# File lib/ctioga2/graphics/styles/factory.rb, line 454 def get_parameter(target) if ! parameters.key? target raise "Unkown parameter: #{target}" else return parameters[target] end end
Returns the class parameters hash
# File lib/ctioga2/graphics/styles/factory.rb, line 463 def parameters return self.class.parameters end
Resolve potential links in the form of :=stuff within the given hash, and returns a new version of the hash.
warning the h parameter is completely destroyed in the process
# File lib/ctioga2/graphics/styles/factory.rb, line 473 def resolve_links(h) tv = {} # First, copy plain values for k,v in h if v.is_a?(Symbol) && v.to_s =~ /^(=|->)/ # We keep for later else tv[k] = v h.delete(k) end end # Now, we will iterate over the remaining things; we will # stop with an error if the number of remaining keys does # not decrease after one step while h.size > 0 pre_size = h.size for k,v in h v.to_s =~ /^(?:=|->)(\S+)/ target = $1 if CurveStyleFactory.name_to_target[target] target = CurveStyleFactory.name_to_target[target] end if tv.key? target tv[k] = tv[target] h.delete(k) end end if h.size >= pre_size raise "Error: infinite recursion loop while gathering styles" end end return tv end