You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

173 lines
5.1 KiB

require 'yaml'
require 'pp'
require 'squib'
require 'squib/card'
require 'squib/progress'
require 'squib/input_helpers'
require 'squib/constants'
# The project module
#
# @api public
module Squib
# The main interface to Squib. Provides a front-end porcelain whereas the Card class interacts with the graphics plumbing.
#
# @api public
class Deck
include Enumerable
include Squib::InputHelpers
# :nodoc:
# @api private
attr_reader :width, :height
# :nodoc:
# @api private
attr_reader :cards
# :nodoc:
# @api private
attr_reader :text_hint
# :nodoc:
# @api private
attr_reader :layout, :config
# Squib's constructor that sets the immutable properties.
#
# This is the starting point for Squib. In providing a block to the constructor, you have access to all of Deck's instance methods.
# The documented methods in Deck are the ones intended for use by most users.
# If your game requires multiple different sizes or orientations, I recommend using multiple `Squib::Deck`s in your `deck.rb`. You can modify the internals of `Squib::Deck` (e.g. `@cards`), but that's not recommended.
# @example
# require 'squib'
# Squib::Deck.new do
# text str: 'Hello, World!'
# end
#
# @param width [Integer] the width of each card in pixels
# @param height [Integer] the height of each card in pixels
# @param cards [Integer] the number of cards in the deck
# @param dpi [Integer] the pixels per inch when rendering out to PDF or calculating using inches.
# @param config [String] the file used for global settings of this deck
# @param block [Block] the main body of the script.
# @api public
def initialize(width: 825, height: 1125, cards: 1, dpi: 300, config: 'config.yml', layout: nil, &block)
@width=width; @height=height
@dpi = dpi
@font = Squib::SYSTEM_DEFAULTS[:default_font]
@cards = []
@custom_colors = {}
@img_dir = '.'
@progress_bar = Squib::Progress.new(false)
@text_hint = :off
cards.times{ @cards << Squib::Card.new(self, width, height) }
load_config(config)
load_layout(layout)
if block_given?
instance_eval(&block)
end
end
# Directly accesses the array of cards in the deck
#
# @api private
def [](key)
@cards[key]
end
# Iterates over each card in the deck
#
# @api private
def each(&block)
@cards.each { |card| block.call(card) }
end
# Shows a descriptive place of the location
#
# @api private
def location(opts)
opts[:layout] || (" @ #{opts[:x]},#{opts[:y]}")
end
# Load the configuration file, if exists, overriding hardcoded defaults
# @api private
def load_config(file)
if File.exists?(file) && config = YAML.load_file(file)
config = Squib::CONFIG_DEFAULTS.merge(config)
@dpi = config['dpi'].to_i
@text_hint = config['text_hint']
@progress_bar.enabled = config['progress_bars']
@custom_colors = config['custom_colors']
@img_dir = config['img_dir']
end
end
# Load the layout configuration file, if exists
# @api private
def load_layout(file)
return if file.nil?
@layout = {}
yml = YAML.load_file(file)
yml.each do |key, value|
@layout[key] = recurse_extends(yml, key, {})
end
end
# Process the extends recursively
# :nodoc:
# @api private
def recurse_extends(yml, key, visited )
assert_not_visited(key, visited)
return yml[key] unless has_extends?(yml, key)
visited[key] = key
parent_keys = [yml[key]['extends']].flatten
h = {}
parent_keys.each do |parent_key|
from_extends = yml[key].merge(recurse_extends(yml, parent_key, visited)) do |key, child_val, parent_val|
if child_val.to_s.strip.start_with?('+=')
parent_val + child_val.sub("+=",'').strip.to_f
elsif child_val.to_s.strip.start_with?('-=')
parent_val - child_val.sub("-=",'').strip.to_f
else
child_val #child overrides parent when merging, no +=
end
end
h = h.merge(from_extends) do |key, older_sibling, younger_sibling|
younger_sibling #when two siblings have the same entry, the "younger" (lower one) overrides
end
end
return h
end
# Does this layout entry have an extends field?
# i.e. is it a base-case or will it need recursion?
# :nodoc:
# @api private
def has_extends?(yml, key)
yml[key].key?('extends')
end
# Safeguard against malformed circular extends
# :nodoc:
# @api private
def assert_not_visited(key, visited)
if visited.key? key
raise "Invalid layout: circular extends with '#{key}'"
end
end
##################
### PUBLIC API ###
##################
require 'squib/api/background'
require 'squib/api/data'
require 'squib/api/image'
require 'squib/api/save'
require 'squib/api/settings'
require 'squib/api/shapes'
require 'squib/api/text'
require 'squib/api/units'
end
end