lib/vedeu/geometries/dsl/dsl.rb
# frozen_string_literal: true
module Vedeu
module Geometries
# Geometry allows the configuration of the position and size of an
# interface. Within Vedeu, as the same for ANSI terminals, has the
# origin at top-left, y = 1, x = 1. The 'y' coordinate is
# deliberately first.
#
# The Geometry DSL can be used within the Interface DSL or
# standalone. Here are example of declarations for a `geometry`
# block:
#
# A standalone geometry definition:
#
# Vedeu.geometry :some_interface do
# height 5 # Sets the height of the view to 5
# width 20 # Sets the width of the view to 20
# x 3 # Start drawing 3 spaces from left
# y 10 # Start drawing 10 spaces from top
# xn 30 # Stop drawing 30 spaces from the left
# yn 20 # Stop drawing 20 spaces from top
# end
#
# An interface including a geometry definition:
#
# Vedeu.interface :some_interface do
# geometry do
# height 5
# width 20
# x 3
# y 10
# xn 30
# yn 20
# end
# # ... some code here
# end
#
# If a declaration is omitted for `height` or `width` the full
# remaining space available in the terminal will be used. `x` and
# `y` both default to 1.
#
# You can also make a geometry declaration dependent on another
# view:
#
# Vedeu.interface :other_panel do
# # ... some code here
# end
#
# Vedeu.interface :main do
# geometry do
# height 10
# y { use(:other_panel).south }
# end
# # ... some code here
# end
#
#
# This view will begin just below "other\_panel".
#
# This crude ASCII diagram represents a Geometry within Vedeu,
# each of the labels is a value you can access or define.
#
# x north xn # north: y - 1
# y +--------------+ # top: y
# | top | # west: x - 1
# | | # left: x
# west | left right | east # right: xn
# | | # east: xn + 1
# | bottom | # bottom: yn
# yn +--------------+ # south: yn + 1
# south
#
# @api public
#
class DSL
include Vedeu::Common
include Vedeu::DSL
include Vedeu::DSL::Geometry
include Vedeu::DSL::Use
# Align the interface/view horizontally or vertically within
# the terminal.
#
# {include:file:docs/dsl/by_method/geometry/align.md}
# @param vertical [Symbol] One of :bottom, :middle, :none, :top.
# @param horizontal [Symbol] One of :center, :centre, :left,
# :none, :right.
# @param width [Fixnum] The number of characters/columns wide;
# this is required when the given value for horizontal is any
# value other than :none.
# @param height [Fixnum] The number of lines/rows tall; this is
# required when the given value for vertical is any value
# other than :none.
# @macro raise_invalid_syntax
# @return [Vedeu::Geometries::Geometry]
def align(vertical: :none, horizontal: :none, width: nil, height: nil)
horizontal_alignment(horizontal, width)
vertical_alignment(vertical, height)
end
# @param value [Symbol] One of :center, :centre, :left, :none,
# :right.
# @param width [Fixnum] The number of characters/columns.
# @param x [Fixnum] When given, sets the x coordinate.
# @return [Vedeu::Geometries::Geometry]
def horizontal_alignment(value = :none, width = nil, x = nil)
alignment = Vedeu::Coercers::HorizontalAlignment.validate(value)
model.width = width if width
model.horizontal_alignment = alignment
model.x = x if x
model
end
# @param value [Symbol] One of :bottom, :middle, :none, :top.
# @param height [Fixnum] The number of lines/rows.
# @param y [Fixnum] When given, sets the y coordinate.
# @return [Vedeu::Geometries::Geometry]
def vertical_alignment(value = :none, height = nil, y = nil)
alignment = Vedeu::Coercers::VerticalAlignment.validate(value)
model.height = height if height
model.vertical_alignment = alignment
model.y = y if y
model
end
# {include:file:docs/dsl/by_method/geometry/align_bottom.md}
# @param height [Fixnum] The number of lines/rows.
# @return [Vedeu::Geometries::Geometry]
def align_bottom(height = nil)
y = if height
Vedeu.height - height
elsif model.height
Vedeu.height - model.height
end
vertical_alignment(:bottom, height, y)
end
# {include:file:docs/dsl/by_method/geometry/align_centre.md}
# @param width [Fixnum] The number of characters/columns.
# @return [Vedeu::Geometries::Geometry]
def align_centre(width = nil)
x = if width
Vedeu.centre_x - (width / 2)
elsif model.width
Vedeu.centre_x - (model.width / 2)
end
horizontal_alignment(:centre, width, x)
end
alias align_center align_centre
# {include:file:docs/dsl/by_method/geometry/align_left.md}
# @param width [Fixnum] The number of characters/columns.
# @return [Vedeu::Geometries::Geometry]
def align_left(width = nil)
horizontal_alignment(:left, width)
end
# {include:file:docs/dsl/by_method/geometry/align_middle.md}
# @param height [Fixnum] The number of lines/rows.
# @return [Vedeu::Geometries::Geometry]
def align_middle(height = nil)
y = if height
Vedeu.centre_y - (height / 2)
elsif model.height
Vedeu.centre_y - (model.height / 2)
end
vertical_alignment(:middle, height, y)
end
# {include:file:docs/dsl/by_method/geometry/align_right.md}
# @param width [Fixnum] The number of characters/columns.
# @return [Vedeu::Geometries::Geometry]
def align_right(width = nil)
x = if width
Vedeu.width - width
elsif model.width
Vedeu.width - model.width
end
horizontal_alignment(:right, width, x)
end
# {include:file:docs/dsl/by_method/geometry/align_top.md}
# @param height [Fixnum] The number of lines/rows.
# @return [Vedeu::Geometries::Geometry]
def align_top(height = nil)
vertical_alignment(:top, height)
end
# {include:file:docs/dsl/by_method/geometry/columns.md}
# @param value [Fixnum]
# @macro raise_out_of_range
# @return [Fixnum|Vedeu::Error::OutOfRange]
def columns(value)
Vedeu::Geometries::Grid.columns(value)
end
# {include:file:docs/dsl/by_method/geometry/height.md}
# @param value [Fixnum]
# @return [Fixnum]
def height(value)
model.height = proc { value }
end
alias height= height
# {include:file:docs/dsl/by_method/geometry/rows.md}
# @param value [Fixnum]
# @macro raise_out_of_range
# @return [Fixnum]
def rows(value)
Vedeu::Geometries::Grid.rows(value)
end
# {include:file:docs/dsl/by_method/geometry/width.md}
# @param value [Fixnum] The number of characters/columns.
# @return [Fixnum]
def width(value)
model.width = proc { value }
end
alias width= width
# {include:file:docs/dsl/by_method/geometry/x.md}
# @param value [Fixnum]
# @macro param_block
# @return [Fixnum]
def x(value = 1, &block)
return model.x = block if block_given?
model.x = value
end
alias x= x
# {include:file:docs/dsl/by_method/geometry/xn.md}
# @param value [Fixnum]
# @macro param_block
# @return [Fixnum]
def xn(value = 1, &block)
return model.xn = block if block_given?
model.xn = value
end
alias xn= xn
# {include:file:docs/dsl/by_method/geometry/y.md}
# @param value [Fixnum]
# @macro param_block
# @return [Fixnum]
def y(value = 1, &block)
return model.y = block if block_given?
model.y = value
end
alias y= y
# {include:file:docs/dsl/by_method/geometry/yn.md}
# @param value [Fixnum]
# @macro param_block
# @return [Fixnum]
def yn(value = 1, &block)
return model.yn = block if block_given?
model.yn = value
end
alias yn= yn
end # DSL
end # Geometries
# @api public
# @!method geometry
# @see Vedeu::Geometries::DSL.geometry
def_delegators Vedeu::Geometries::DSL,
:geometry
end # Vedeu