Acme::TextLayout - Layout things in a grid, as described textually
$tl = Acme::TextLayout->new; $tl->instantiate(text => $pattern);
For a GUI, controlling layout (especially on resize) can be difficult, especially if your layout is complex. When looking at a GUI, I came to the realization that I could express the layout nicely like this:
AAAAAAAAAAAAAAAA BBBBxxxxxxxxxxxx BBBBxxxxxxxxxxxx DDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDD DDDDDDDDDDDDDDDD %%%%%%%%%%%%%GGG
Where each group of contiguous, like characters specifies a screen region.
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 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).
$tl = Acme::TextLayout->new([%opts]);
Create an instance of this class. See instantiate to do anything useful.
$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.
($ymin, $ymax, $xmin, $xmax) = $tl->range($char);
The range of positions for the specified character. Note order of arguments returned.
@chars = $tl->characters();
Return list of all of the unique characters in our pattern.
($width, $height) = $tl->text_size();
Find width & height of our pattern in character units. This may be important since the user of a GUI is free to resize in a way that messes up the relative aspect ratio as you defined in the pattern. And you may want to correct this awful situation.
Return width of our pattern (in # characters).
Return height of our pattern (in # characters).
@bbox = $tl->map_range($width, $height, $char);
Map the relative position and size of the indicated character ($char) region in our pattern to a real XY coordinate space.
@bbox is the bounding box, returned as ($x1, $y1, $x2, $y2), where $x1, $y1 is the upper left corner, and $x2, $y2 is the lower right.
Because this was written (primarily) to interface to a GUI, the origin is assumed to be 0,0 in the upper left corner, with x bigger to the right, and y bigger down. Adjust as necessary to fit your problem domain.
@r = $tl->above($char);
Return a list (possibly empty) of each of the characters above (and adjacent) to the specified character.
@r = $tl->below($char);
Return a list (possibly empty) of each of the characters below (and adjacent) to the specified character.
@r = $tl->left($char);
Return a list (possibly empty) of each of the characters to the left (and adjacent) to the specified character.
@r = $tl->right($char);
Return a list (possibly empty) of each of the characters to the right (and adjacent) to the specified character.
($xpercent, $ypercent) = $tl->range_as_percent($char);
Returns the percentage of x and y that this character consumes in the pattern. Number returned for each is <= 1.0.
@chars = $tl->order([$line]);
Return the order of the characters encountered on line $line (zero-based). $line defaults to zero if not specified.
$stat = $tl->only_one();
Returns 1 if there is only a single character in your pattern, 0 if there are more.
<cramps.the at gmail.com>
There shouldn't be any. But I am a human, and do mess up sometimes.
Please report any bugs or feature requests to
bug-acme-textlayout at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Acme-TextLayout. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
You can find documentation for this module with the perldoc command.
You can also look for information at:
Captain Beefheart and Ella Guru. So there.
Copyright 2009 X Cramps, all rights reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.