module Vedeu module DSL # 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 # class Geometry include Vedeu::DSL include Vedeu::DSL::Use # Specify the geometry of an interface or view with a simple DSL. # # Vedeu.geometry 'some_interface' do # # ... # end # # @param name [String] The name of the interface or view to which this # geometry belongs. # @param block [Proc] # @raise [Vedeu::InvalidSyntax] The required block was not given. # @return [Vedeu::Geometry] def self.geometry(name, &block) fail Vedeu::InvalidSyntax, 'block not given' unless block_given? Vedeu::Geometry.build({ name: name }, &block).store end # Returns an instance of DSL::Geometry. # # @param model [Vedeu::Geometry] # @param client [Object] # @return [Vedeu::DSL::Geometry] def initialize(model, client = nil) @model = model @client = client end # Instructs Vedeu to calculate x and y geometry automatically based on the # centre character of the terminal, the width and the height. # # Vedeu.geometry 'some_interface' do # centred false # or... # # centred true # or... # centred! # or... # # ... some code # end # # @param value [Boolean] Any value other than nil or false will evaluate # to true. # @return [Boolean] def centred(value = true) boolean = value ? true : false model.centred = boolean end alias_method :centred!, :centred # Returns the width in characters for the number of columns specified. # # Vedeu.geometry 'main_interface' do # # ... some code # width columns(9) # Vedeu.width # => 92 (for example) # # 92 / 12 = 7 # # 7 * 9 = 63 # # Therefore, width is 63 characters. # end # # @param value [Fixnum] # @raise [Vedeu::OutOfRange] When the value parameter is not between 1 and # 12 inclusive. # @return [Fixnum|Vedeu::OutOfRange] def columns(value) Vedeu::Grid.columns(value) end # Specify the number of characters/rows/lines tall the interface will be. # This value will be ignored when `y` and `yn` are set. # # Vedeu.geometry 'some_interface' do # height 8 # # ... some code # end # # @param value [Fixnum] # @return [Fixnum] def height(value) model.height = proc { value } end # Returns the height in characters for the number of rows specified. # # Vedeu.geometry 'main_interface' do # # ... some code # height rows(3) # Vedeu.height # => 38 (for example) # # 38 / 12 = 3 # # 3 * 3 = 9 # # Therefore, height is 9 characters. # end # # @param value [Fixnum] # @raise [Vedeu::OutOfRange] When the value parameter is not between 1 and # 12 inclusive. # @return [Fixnum] def rows(value) Vedeu::Grid.rows(value) end # Specify the number of characters/columns wide the interface will be. # This value will be ignored when `x` and `xn` are set. # # Vedeu.geometry 'some_interface' do # width 25 # # ... some code # end # # @param value [Fixnum] # @return [Fixnum] def width(value) model.width = proc { value } end # Specify the starting x position (column) of the interface. # # Vedeu.geometry 'some_interface' do # x 7 # start on column 7. # # x { use('other_interface').east } # start on column 8, if # # ... some code # `other_interface` changes # end # position, `some_interface` will # # too. # # @param value [Fixnum] # @param block [Proc] # @return [Fixnum] def x(value = 1, &block) return model.x = block if block_given? model.x = value end # Specify the ending x position (column) of the interface. # This value will override `width`. # # Vedeu.geometry 'some_interface' do # xn 37 # end at column 37. # # xn { use('other_interface').right } # when `other_interface` # # changes position, # # ... some code # `some_interface` will too. # end # # @param value [Fixnum] # @param block [Proc] # @return [Fixnum] def xn(value = 1, &block) return model.xn = block if block_given? model.xn = value end # Specify the starting y position (row/line) of the interface. # # Vedeu.geometry 'some_interface' do # y 4 # start at row 4 # # y { use('other_interface').north } # start on row/line 3, when # # ... some code # `other_interface` changes # end # position, `some_interface` # # will too. # # @param value [Fixnum] # @param block [Proc] # @return [Fixnum] def y(value = 1, &block) return model.y = block if block_given? model.y = value end # Specify the ending y position (row/line) of the interface. # This value will override `height`. # # Vedeu.geometry 'some_interface' do # yn 24 # end at row 24. # # yn { use('other_interface').bottom } # if `other_interface` changes # # ... some code # position, `some_interface` # end # will too. # # @param value [Fixnum] # @param block [Proc] # @return [Fixnum] def yn(value = 1, &block) return model.yn = block if block_given? model.yn = value end protected # @!attribute [r] client # @return [Object] attr_reader :client # @!attribute [r] model # @return [Vedeu::Geometry] attr_reader :model end # Geometry end # DSL end # Vedeu