# frozen_string_literal: true module Vedeu module Geometries # Change coordinates into an escape sequence to set the cursor # position. # # @api private # class Position # @!attribute [r] y # @return [Fixnum] attr_reader :y alias first y # @!attribute [r] x # @return [Fixnum] attr_reader :x alias last x class << self extend Forwardable def_delegators Vedeu::Coercers::Position, :coerce # Convenience constructor for Vedeu::Geometries::Position. # # @param (see #initialize) def [](y = 1, x = 1) new(y, x) end end # Eigenclass # Initializes a new instance of Vedeu::Geometries::Position. # # @param y [Fixnum] The row/line position. # @param x [Fixnum] The column/character position. # @return [Vedeu::Geometries::Position] def initialize(y = 1, x = 1) @y = Vedeu::Point.coerce(value: y, max: Vedeu.height).value @x = Vedeu::Point.coerce(value: x, max: Vedeu.width).value freeze end # Converts a position into an index for the terminal. An index # is the position minus 1. # # @return [Array] def as_indices ix = Vedeu::Point.coerce(value: (x - 1), min: 0).value iy = Vedeu::Point.coerce(value: (y - 1), min: 0).value [iy, ix] end # @param other [Vedeu::Geometries::Position] # @return [Fixnum] def <=>(other) if y == other.y x <=> other.x else y <=> other.y end end # An object is equal when its values are the same. # # @param other [Vedeu::Geometries::Position] # @return [Boolean] def eql?(other) self.class == other.class && x == other.x && y == other.y end alias == eql? # Return a tuple containing the y and x coordinates. # # @return [Array] def to_a [y, x] end # @return [String] def to_ast ":y#{y}_x#{x}" end # Return the position as a Hash. # # @return [Hash Fixnum|NilClass>] def to_h { position: { y: y, x: x, }, } end alias to_hash to_h # Return the escape sequence required to position the cursor at # a particular point on the screen. When passed a block, will do # the aforementioned, call the block and then reposition to this # location. # # @param block [Proc] # @return [String] # @yieldreturn [String] Returns the block wrapped in position # escape sequences. def to_s(&block) return "#{sequence}#{yield}" if block_given? sequence end alias to_str to_s # Increase y coordinate; moves down. # # @return [Vedeu::Geometries::Position] def down Vedeu::Geometries::Position.new(y + 1, x) end # Decrease x coordinate; moves left. # # @return [Vedeu::Geometries::Position] def left Vedeu::Geometries::Position.new(y, x - 1) end # Increase x coordinate; moves right. # # @return [Vedeu::Geometries::Position] def right Vedeu::Geometries::Position.new(y, x + 1) end # Decrease y coordinate; moves up. # # @return [Vedeu::Geometries::Position] def up Vedeu::Geometries::Position.new(y - 1, x) end private # Returns the escape sequence to reposition the cursors at the # coordinates specified by x and y. # # @return [String] def sequence "\e[#{y};#{x}H" end end # Position end # Geometries end # Vedeu