lib/whirled_peas/template/element.rb in whirled_peas-0.4.1 vs lib/whirled_peas/template/element.rb in whirled_peas-0.5.0

- old
+ new

@@ -1,230 +1,13 @@ -require_relative '../utils/title_font' - -require_relative 'settings' - module WhirledPeas - module UI - STRINGALBE_CLASSES = [FalseClass, Float, Integer, NilClass, String, Symbol, TrueClass] - + module Template class Element - attr_accessor :preferred_width, :preferred_height attr_reader :name, :settings def initialize(name, settings) @name = name @settings = settings end end private_constant :Element - - class TextElement < Element - attr_reader :lines - - def initialize(name, settings) - super(name, TextSettings.merge(settings)) - end - - def lines=(val) - unless STRINGALBE_CLASSES.include?(val.class) - raise ArgmentError, "Unsupported type for TextElement: #{val.class}" - end - if settings.title_font - @lines = Utils::TitleFont.to_s(val.to_s, settings.title_font).split("\n") - else - @lines = [val.to_s] - end - @preferred_width = settings.width || @lines.first.length - @preferred_height = @lines.length - end - - def inspect(indent='') - dims = unless preferred_width.nil? - "#{indent + ' '}- Dimensions: #{preferred_width}x#{preferred_height}" - end - [ - "#{indent}+ #{name} [#{self.class.name}]", - dims, - "#{indent + ' '}- Settings", - settings.inspect(indent + ' ') - ].compact.join("\n") - end - end - - class ComposableElement < Element - class << self - def next_name - @counter ||= 0 - @counter += 1 - "Element-#{@counter}" - end - end - - def initialize(name, settings) - super - end - - def children - @children ||= [] - end - - def add_text(name=self.class.next_name, &block) - element = TextElement.new(name, settings) - element.lines = yield nil, element.settings - children << element - end - - def add_box(name=self.class.next_name, &block) - element = BoxElement.new(name, settings) - value = yield element, element.settings - children << element - if element.children.empty? && STRINGALBE_CLASSES.include?(value.class) - element.add_text { value.to_s } - end - end - - def add_grid(name=self.class.next_name, &block) - element = GridElement.new(name, settings) - values = yield element, element.settings - children << element - if element.children.empty? && values.is_a?(Array) - values.each { |v| element.add_text { v.to_s } } - end - end - - def inspect(indent='') - kids = children.map { |c| c.inspect(indent + ' ') }.join("\n") - dims = unless preferred_width.nil? - "#{indent + ' '}- Dimensions: #{preferred_width}x#{preferred_height}" - end - [ - "#{indent}+ #{name} [#{self.class.name}]", - dims, - "#{indent + ' '}- Settings", - settings.inspect(indent + ' '), - "#{indent + ' '}- Children", - kids - ].compact.join("\n") - end - - private - - def margin_width - settings.margin.left + settings.margin.right - end - - def margin_height - settings.margin.top + settings.margin.bottom - end - - def outer_border_width - (settings.border.left? ? 1 : 0) + (settings.border.right? ? 1 : 0) - end - - def outer_border_height - (settings.border.top? ? 1 : 0) + (settings.border.bottom? ? 1 : 0) - end - - def inner_border_width - settings.border.inner_vert? ? 1 : 0 - end - - def inner_border_height - settings.border.inner_horiz? ? 1 : 0 - end - - def padding_width - settings.padding.left + settings.padding.right - end - - def padding_height - settings.padding.top + settings.padding.bottom - end - end - - class Template < ComposableElement - def initialize(settings=TemplateSettings.new) - super('TEMPLATE', settings) - end - end - - class BoxElement < ComposableElement - attr_writer :content_width, :content_height - - def initialize(name, settings) - super(name, BoxSettings.merge(settings)) - end - - def self.from_template(template, width, height) - box = new(template.name, template.settings) - template.children.each { |c| box.children << c } - box.content_width = box.preferred_width = width - box.content_height = box.preferred_height = height - box - end - - def content_width - @content_width ||= begin - child_widths = children.map(&:preferred_width) - width = settings.horizontal_flow? ? child_widths.sum : (child_widths.max || 0) - [width, *settings.width].max - end - end - - def preferred_width - @preferred_width ||= - margin_width + outer_border_width + padding_width + content_width - end - - def content_height - @content_height ||= begin - child_heights = children.map(&:preferred_height) - settings.vertical_flow? ? child_heights.sum : (child_heights.max || 0) - end - end - - def preferred_height - @preferred_height ||= - margin_height + outer_border_height + padding_height + content_height - end - end - - class GridElement < ComposableElement - def initialize(name, settings) - super(name, GridSettings.merge(settings)) - end - - def col_width - return @col_width if @col_width - @col_width = 0 - children.each do |child| - @col_width = child.preferred_width if child.preferred_width > @col_width - end - @col_width - end - - def row_height - return @row_height if @row_height - @row_height = 0 - children.each do |child| - @row_height = child.preferred_height if child.preferred_height > @row_height - end - @row_height - end - - def preferred_width - margin_width + - outer_border_width + - settings.num_cols * (padding_width + col_width) + - (settings.num_cols - 1) * inner_border_width - end - - def preferred_height - num_rows = (children.length / settings.num_cols).ceil - margin_height + - outer_border_height + - num_rows * (padding_height + row_height) + - (num_rows - 1) * inner_border_height - end - end end end