Acme-TextLayout

 view release on metacpan or  search on metacpan

lib/Acme/TextLayout.pm  view on Meta::CPAN

  DDDDDDDDDDDDDDDD
  DDDDDDDDDDDDDDDD
  DDDDDDDDDDDDDDDD
  %%%%%%%%%%%%%GGG

Where each group of contiguous, like characters specifies a screen
region.

B<Very important>: space is not legal. Nor should you use "-", trust
me. A space (" ") will cause you to die, but a "-" is accepted,
but is used by other modules for other things. BEWARE!

To me, this gives an easy-to-grasp pictorial of the GUI
layout, as long as one notes WTF the letters and symbols represent.
The only caveat is that the collection of like characters/symbols
making the pattern must be adjacent, and must be rectangular. And
the overall pattern must be rectangular.

Note that this textual arrangement can be as big as you want.
It's all relative. Although it might not look like it on
the screen in your editor of choice, all spacing is assummed to
be the same in X and Y. Thus, the aspect ratio of the above
pattern is 16/7 (width/height).

To be useful for a GUI, one must be able to map this goofy space
into screen coordinates. That's what the B<map_range> function is
for (see below).

Now, I know what you must be thinking: is this guy nuts? Why not
use brand-X fancy GUI layout tool? Well, the fact is that those
are nice and easy for the initial layout, but they generally generate
code with precise XY coordinates in them, which makes resizing almost
impossible.

The idea here is that we use the above textual layout to specify
all the relative positions of things, then map this to a real
coordinate system, preserving the spatial relativity and size
associations.

I wrote this for use in a GUI application, but figured it might have
use elsewhere. Hence, this class. If you find a novel use for it,
please let me know what it is (email address in this document).


=head1 METHODS

=cut

=head2 B<new>

  $tl = Acme::TextLayout->new([%opts]);

Create an instance of this class. See B<instantiate> to do anything useful.

=cut

sub new {
    my $class = shift;
    my %opts = @_;
    my $self = \%opts;
    bless $self, $class;
    $.Class = $class;
    return $self;
}

=head2 B<instantiate>

  $tl->instantiate(text => ??);
  -or-
  $tl->instantiate(file => ??);

Specify the textual layout pattern we are interested in, either
from a text string or a file.

Returns undef if something wrong with your input.

=cut

sub instantiate {
    my ($self, %opts) = @_;
    my $file = $opts{file};
    my $text = $opts{text};

    # reset state on new instantiation
    $.textRef = [];
    $.Ranges  = {};
    $.widest = undef;
    $.chars  = {};
    $.Above = $.Below = $.Left = $.Right = undef;

    if (defined $file) {
        my $fh = FileHandle->new($file);
        return unless defined $fh;
        my @text = <$fh>;
        $fh->close;
        chomp foreach @text;
        s/^\s+// foreach @text;
        $text = [ @text ];
        ./_widest(\@text);
    }
    elsif (defined $text) {
        my @text = split(/\n{1}/, $text);
        s/^\s+// foreach @text;
        $text = [ @text ];
        ./_widest(\@text);
    }
    else {
        return undef;
    }

    ./_whats_in_there($text);
    ./_widest($text);
    $.textRef = $text;
    map {
        return undef unless length($_) == $.widest;
    } @{$.textRef};

    my %Ranges;
    my %chars = %.chars;
    map {
        my $C = $_;



( run in 1.641 second using v1.01-cache-2.11-cpan-39bf76dae61 )