Нели обнови решението на 26.11.2014 16:56 (преди почти 10 години)
+module UI
+ class Node
+ attr_accessor :styles
+ attr_accessor :type
+ attr_accessor :output
+ attr_accessor :width
+
+ def initialize(type, styles = {})
+ @styles = styles
+ @type = type
+ @output = ''
+ @width = 0
+ end
+
+ def label(text:,**my)
+ my[:style] = styles[:style] if my[:style].nil?
+ styled = ! my[:style].nil? ? "#{text}".send(my[:style]) : "#{text}"
+ output << "#{my[:border]}" << styled << "#{my[:border]}"
+ output << "\n" if self.type == :vertical
+ @width = "#{text}".length if @width < "#{text}".length
+ end
+
+ def horizontal(**my, &block)
+ my[:style] = styles[:style] if my[:style].nil?
+ me = Node.new :horizontal, my
+ me.instance_eval &block
+ output << (my[:border].nil? ? me.output : apply_border(me))
+ @width = me.width if @width < me.width
+ output << "\n" if self.type == :vertical
+ end
+
+ def vertical(**my, &block)
+ my[:style] = styles[:style] if my[:style].nil?
+ me = Node.new :vertical, my
+ me.instance_eval &block
+ apply_border me if ! my[:border].nil? && me.width > 0
+ @width = me.width if @width < me.width
+ #self.type == :horizontal ? magic(me) : output << me.output
+ output << me.output
+ end
+
+ def apply_border(node)
+ builder = ''
+ node.output.each_line do |line|
+ builder << "#{node.styles[:border]}" << line.chomp.ljust(node.width)
+ builder << "#{node.styles[:border]}" << "\n"
+ end
+ node.width += node.styles[:border].length
+ node.output = builder
+ end
+=begin
+ def magic(node)
+ node.output
+
+ #if there is a vertical section in a horizontal one
+ puts @output
+ rows = output.split("\n").zip(node.output.split("\n"))
+ builder = ''
+ rows.each do |first, second|
+ builder << (line = first.ljust(width) << second)
+ #@width = @width < line.length ? line.length : @width
+ end
+ output << builder
+
+ end
+=end
+ end
+
+ class TextScreen
+ def self.draw
+ @@drawer = Node.new(:horizontal)
+ @@drawer.instance_eval &Proc.new
+ @@drawer.output
+ end
+ end
+end