diff --git a/API.md b/API.md index 2c2c7a7..d89ccfe 100644 --- a/API.md +++ b/API.md @@ -1,5 +1,7 @@ # Squib API +The Squib DSL is based on a collection of methods provided to the `Squib::Deck` class. The general philosophy of Squib is to specify as little as possible (i.e. great defaults ) + # Squib::Deck and Squib::Card Squib essentially has two main classes: `Deck` and `Card`. `Deck` is the front-end, and `Card` is the back-end. The contract of `Deck` is to do the various manipulations of options and then delegate the operation to `Card` to do the low-level graphical operations. @@ -35,17 +37,32 @@ Many more examples can be found in `ranges.rb` in the [samples](https://github.c # Pixels and Other Units -By default, Squib thinks in pixels. This decision was made so that we can have pixel-perfect layouts without automatically scaling everything, even though working in units is sometimes easier. To convert, we provide the `Deck#inch` method, as shown in +By default, Squib thinks in pixels. This decision was made so that we can have pixel-perfect layouts without automatically scaling everything, even though working in units is sometimes easier. To convert, we provide the `Deck#inch` method, as shown in `samples/units.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/units.rb) -`samples/units.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/units.rb) +{include:file:samples/units.rb} # Specifying Colors -Squib uses the `rcairo` [color parser](https://github.com/rcairo/rcairo/blob/master/lib/cairo/color.rb) to accepts a variety of color specifications, along with over [300 pre-defined constants](https://github.com/rcairo/rcairo/blob/master/lib/cairo/colors.rb). Here are some examples from `samples/colors.rb` found [here](https://github.com/andymeneely/squib/tree/master/samples/colors.rb) +Colors can be specified in a wide variety of ways, mostly in a hex-string. Take a look at the examples from `samples/colors.rb`, found [here](https://github.com/andymeneely/squib/tree/master/samples/colors.rb) {include:file:samples/colors.rb} +Under the hood, Squib uses the `rcairo` [color parser](https://github.com/rcairo/rcairo/blob/master/lib/cairo/color.rb) to accepts a variety of color specifications, along with over [300 pre-defined constants](https://github.com/rcairo/rcairo/blob/master/lib/cairo/colors.rb). + # Specifying Files -All files opened for reading (e.g. for `png` and `xlsx`) are opened relative to the current directory. +All files opened for reading or writing (e.g. for `png` and `xlsx`) are opened relative to the current directory. Files opened for writing (e.g. for `save_png`) will be overwritten without warning. + +# Custom Layouts + +Working with x-y coordinates can be tiresome, and ideally everything in a game prototype should be data-driven. To counter this, many Squib methods allow for a `layout` to be set. In essence, layouts are a way of setting default values for `x, y, width` and `height`. + +To use a layout, set the `layout:` option on a `Deck.new` command to point to a YAML file. Any command that allows a `layout` option can be set with a Ruby symbol or String, and the command will then load the specified `x`, `y`, `width`, and `height`. The individual command can also override these options. + +Note: YAML is very finnicky about having tabs in the file. Use two spaces for indentation instead. + +See the `use_layout` sample found [here](https://github.com/andymeneely/squib/tree/master/samples/) + +{include:file:samples/use_layout.rb} + diff --git a/lib/squib/api/image.rb b/lib/squib/api/image.rb index 1b59d18..8171bdf 100644 --- a/lib/squib/api/image.rb +++ b/lib/squib/api/image.rb @@ -16,7 +16,7 @@ module Squib # @return [nil] Returns nil # @api public def png(opts = {}) - opts = needs(opts, [:range, :files, :x, :y, :alpha]) + opts = needs(opts, [:range, :files, :x, :y, :alpha, :layout]) opts[:range].each do |i| @cards[i].png(opts[:file][i], opts[:x], opts[:y], opts[:alpha]) end @@ -37,7 +37,7 @@ module Squib # @return [nil] Returns nil # @api public def svg(opts = {}) - p = needs(opts,[:range, :files, :svgid, :x, :y, :width, :height]) + p = needs(opts,[:range, :files, :svgid, :x, :y, :width, :height, :layout]) p[:range].each do |i| @cards[i].svg(p[:file][i], p[:id], p[:x], p[:y], p[:width], p[:height]) end diff --git a/lib/squib/api/shapes.rb b/lib/squib/api/shapes.rb index 4045333..f9d3cfc 100644 --- a/lib/squib/api/shapes.rb +++ b/lib/squib/api/shapes.rb @@ -20,7 +20,7 @@ module Squib # @api public def rect(opts = {}) opts = needs(opts, [:range, :x, :y, :width, :height, :radius, - :fill_color, :stroke_color, :stroke_width]) + :fill_color, :stroke_color, :stroke_width, :layout]) opts[:range].each do |i| @cards[i].rect(opts[:x], opts[:y], opts[:width], opts[:height], opts[:x_radius], opts[:y_radius], diff --git a/lib/squib/api/text.rb b/lib/squib/api/text.rb index 816b1bf..96b5b84 100644 --- a/lib/squib/api/text.rb +++ b/lib/squib/api/text.rb @@ -34,7 +34,7 @@ module Squib # @api public def text(opts = {}) opts = needs(opts, [:range, :str, :font, :x, :y, :width, :height, :text_color, :wrap, - :align, :justify, :valign, :ellipsize, :hint]) + :align, :justify, :valign, :ellipsize, :hint, :layout]) opts[:str] = [opts[:str]] * @cards.size unless opts[:str].respond_to? :each opts[:range].each do |i| @cards[i].text(opts[:str][i], opts[:font], opts[:x], opts[:y], opts[:color], opts) diff --git a/lib/squib/constants.rb b/lib/squib/constants.rb index 6094cbe..1d13d74 100644 --- a/lib/squib/constants.rb +++ b/lib/squib/constants.rb @@ -13,6 +13,8 @@ module Squib :sheet => 0, :x => 0, :y => 0, + :x_radius => 0, + :y_radius => 0, :align => :left, :valign => :top, :justify => false, diff --git a/lib/squib/deck.rb b/lib/squib/deck.rb index 49a6c29..9b7d826 100644 --- a/lib/squib/deck.rb +++ b/lib/squib/deck.rb @@ -45,13 +45,14 @@ module Squib # @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', &block) + 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 = [] cards.times{ @cards << Squib::Card.new(self, width, height) } load_config(config) + load_layout(layout) if block_given? instance_eval(&block) end @@ -81,6 +82,13 @@ module Squib end end + # Load the layout configuration file, if exists + # @api private + def load_layout(file) + return if file.nil? + @layout = YAML.load_file(file) + end + ################## ### PUBLIC API ### ################## diff --git a/lib/squib/graphics/shapes.rb b/lib/squib/graphics/shapes.rb index 8fb1478..2ed9227 100644 --- a/lib/squib/graphics/shapes.rb +++ b/lib/squib/graphics/shapes.rb @@ -4,6 +4,7 @@ module Squib # :nodoc: # @api private def rect(x, y, width, height, x_radius, y_radius, fill_color, stroke_color, stroke_width) + width=@width if width==:native; height=@height if height==:native cc = cairo_context cc.rounded_rectangle(x, y, width, height, x_radius, y_radius) cc.set_source_color(stroke_color) diff --git a/lib/squib/input_helpers.rb b/lib/squib/input_helpers.rb index 27d6d85..d4479c5 100644 --- a/lib/squib/input_helpers.rb +++ b/lib/squib/input_helpers.rb @@ -7,6 +7,7 @@ module Squib # @api private def needs(opts, params) + opts = layoutify(opts) if params.include? :layout opts = Squib::SYSTEM_DEFAULTS.merge(opts) opts = rangeify(opts) if params.include? :range opts = fileify(opts) if params.include? :file @@ -24,6 +25,21 @@ module Squib end module_function :needs + def layoutify(opts) + unless opts[:layout].nil? + entry = @layout[opts[:layout].to_s] + unless entry.nil? + %w(x y width height).each do |p| + opts[p.to_sym] ||= entry[p] + end + else + logger.warn "Layout entry #{opts[:layout]} does not exist." + end + end + opts + end + module_function :layoutify + # @api private def formatify(opts) opts[:format] = [opts[:format]].flatten diff --git a/samples/custom-layout.yml b/samples/custom-layout.yml new file mode 100644 index 0000000..6914dbf --- /dev/null +++ b/samples/custom-layout.yml @@ -0,0 +1,25 @@ +frame: + x: 38 + y: 38 + width: 750 + height: 1050 +title: + x: 125 + y: 50 + width: 625 + height: 150 +subtitle: + x: 125 + y: 150 + width: 625 + height: 150 +icon_left: + x: 200 + y: 250 + width: 125 + height: 125 +icon_right: + x: 400 + y: 250 + width: 125 + height: 125 diff --git a/samples/use_layout.rb b/samples/use_layout.rb new file mode 100644 index 0000000..745d930 --- /dev/null +++ b/samples/use_layout.rb @@ -0,0 +1,21 @@ +require 'squib' + +Squib::Deck.new(layout: 'custom-layout.yml') do + background color: :white + + # Layouts are YAML files that specify x, y, width, and height coordinates + rect layout: :frame + + # You can also override a given layout entry in the command + rect layout: :frame, width: 50, height: 50 + + # Any command with x-y-width-height options, we can use a custom layout + text str: 'The Title', layout: :title + png file: 'shiny-purse.png', layout: :icon_left + svg file: 'spanner.svg', layout: :icon_right + + # Strings can also be used in layouts + text str: 'subtitle', layout: 'subtitle' + + save_png prefix: 'layout_' +end \ No newline at end of file