NAME
Tickit::DSL - domain-specific language for Tickit terminal apps
VERSION
version 0.001
SYNOPSIS
use Tickit::DSL;
vbox {
hbox { static 'left' } expand => 1;
hbox { static 'right' } expand => 1;
}
DESCRIPTION
WARNING: This is the first version, has an experimental API, and is subject to change in future. Please get in contact and/or wait for 1.0 if you want something stable.
Provides a simplified interface for writing Tickit applications. This is mainly intended for prototyping:
#!/usr/bin/env perl
use strict;
use warnings;
use Tickit::DSL;
vbox {
# Single line menu at the top of the screen
menubar {
submenu File => sub {
menuitem Open => sub { warn 'open' };
menuspacer;
menuitem Exit => sub { tickit->stop };
};
submenu Edit => sub {
menuitem Copy => sub { warn 'copy' };
menuitem Cut => sub { warn 'cut' };
menuitem Paste => sub { warn 'paste' };
};
menuspacer;
submenu Help => sub {
menuitem About => sub { warn 'about' };
};
};
# A 2-panel layout covers most of the rest of the display
widget {
# Left and right panes:
vsplit {
# A tree on the left, 1/4 total width
widget {
placeholder;
} expand => 1;
# and a tab widget on the right, 3/4 total width
widget {
tabbed {
widget { placeholder } label => 'First thing';
};
} expand => 3;
} expand => 1;
} expand => 1;
# At the bottom of the screen we show the status bar
# statusbar { } show => [qw(clock cpu memory debug)];
# although it's not on CPAN yet so we don't
};
tickit->run;
import
By default we'll import all the known widget shortcuts. To override this, pass a list (possibly empty) on import:
use Tickit::DSL qw();
By default, the synchronous Tickit class will be used. You can make "tickit" refer to a Tickit::Async object instead by passing the :async
tag:
use Tickit::DSL qw(:async);
the default is :sync
, but you can make this explicit:
use Tickit::DSL qw(:sync);
There is currently no support for mixing the two styles in a single application - if :async
or :sync
have already been passed to a previous import, attempting to apply the opposite one will cause an exception.
This is fine:
use Tickit::DSL qw(:sync);
use Tickit::DSL qw();
use Tickit::DSL;
This is not:
use Tickit::DSL qw(:sync);
use Tickit::DSL qw(:async); # will raise an exception
loop
Returns the IO::Async::Loop instance if we're in :async
mode, throws an exception if we're not. See "import" for details.
tickit
Returns (constructing if necessary) the Tickit (or Tickit::Async) instance.
later
Defers a block of code.
later {
print "this happened later\n";
};
Will run the code after the next round of I/O events.
add_widgets
Adds some widgets under an existing widget.
my $some_widget = vbox { };
add_widgets {
vbox { ... };
hbox { ... };
} under => $some_widget;
Returns the widget we added the new widgets under (i.e. the under
parameter).
vbox
Creates a Tickit::Widget::VBox. This is a container, so the first parameter is a coderef which will switch the current parent to the new vbox.
Any additional parameters will be passed to the new Tickit::Widget::VBox instance:
vbox {
...
} class => 'some_vbox';
vbox {
...
} classes => [qw(other vbox)], style => { fg => 'green' };
vsplit
Creates a Tickit::Widget::VSplit. This is a container, so the first parameter is a coderef which will switch the current parent to the new widget. Note that this widget expects 2 child widgets only.
Any additional parameters will be passed to the new Tickit::Widget::VSplit instance:
vsplit {
...
} class => 'some_vsplit';
vsplit {
...
} classes => [qw(other vsplit)], style => { fg => 'green' };
gridbox
Creates a Tickit::Widget::GridBox. This is a container, so the first parameter is a coderef which will switch the current parent to the new widget.
Although any widget is allowed here, you'll probably want all the immediate children to be "gridrow"s.
Any additional parameters will be passed to the new Tickit::Widget::GridBox instance:
gridbox {
gridrow { static 'left'; static 'right' };
gridrow { static 'BL'; static 'BR' };
} style => { col_spacing => 1, row_spacing => 1 };
gridrow
Marks a separate row in an existing Tickit::Widget::GridBox. This behaves something like a container, see "gridbox" for details.
hbox
Creates a Tickit::Widget::HBox. This is a container, so the first parameter is a coderef which will switch the current parent to the new hbox.
Any additional parameters will be passed to the new Tickit::Widget::HBox instance:
hbox {
...
} class => 'some_hbox';
hbox {
...
} classes => [qw(other hbox)], style => { fg => 'green' };
hsplit
Creates a Tickit::Widget::HSplit. This is a container, so the first parameter is a coderef which will switch the current parent to the new widget. Note that this widget expects 2 child widgets only.
Any additional parameters will be passed to the new Tickit::Widget::HSplit instance:
hsplit {
...
} class => 'some_hsplit';
hsplit {
...
} classes => [qw(other hsplit)], style => { fg => 'green' };
scroller
Adds a Tickit::Widget::Scroller. Contents are probably going to be "scroller_text" for now.
scroller {
scroller_text 'line ' . $_ for 1..500;
};
Passes any additional args to the constructor:
scroller {
scroller_text 'line ' . $_ for 1..100;
} gravity => 'bottom';
scroller_text
A text item, expects to be added to a "scroller".
tabbed
Creates a Tickit::Widget::Tabbed instance. Use the "widget" wrapper to set the label when adding new tabs.
tabbed {
widget { static 'some text' } label => 'first tab';
widget { static 'other text' } label => 'second tab';
};
If you want a different ribbon, pass it like so:
tabbed {
widget { static 'some text' } label => 'first tab';
widget { static 'other text' } label => 'second tab';
} ribbon_class => 'Some::Ribbon::Class', tab_position => 'top';
The ribbon_class
parameter may be undocumented.
statusbar
A Tickit::Widget::Statusbar. Not very exciting.
static
Static text. Very simple:
static 'some text';
You can be more specific if you want:
static 'some text', align => 'center';
entry
A Tickit::Widget::Entry input field. Takes a coderef as the first parameter since the on_enter
handler seems like an important feature.
my $rslt = static 'result here';
entry { shift; $rslt->set_text(eval shift) } text => '1 + 3';
tree
A Tickit::Widget::Tree. If it works I'd be amazed.
placeholder
Use this if you're not sure which widget you want yet. It's a Tickit::Widget::Placegrid, so there aren't many options.
placeholder;
vbox {
widget { placeholder } expand => 3;
widget { placeholder } expand => 5;
};
menubar
Menubar courtesy of Tickit::Widget::MenuBar. Every self-respecting app wants one of these.
menubar {
submenu File => sub {
menuitem Exit => sub { tickit->stop };
};
menuspacer;
submenu Help => sub {
menuitem About => sub { warn 'about' };
};
};
submenu
A menu entry in a "menubar". First parameter is used as the label, second is the coderef to populate the widgets (will be called immediately).
See "menubar".
menuspacer
Adds a spacer if you're in a menu. No idea what it'd do if you're not in a menu.
menuitem
A menu is not much use without something in it. See "menubar".
customwidget
A generic function for adding 'custom' widgets - i.e. anything that's not already supported by this module.
This will call the coderef, expecting to get back a Tickit::Widget, then it'll apply that widget to whatever the current parent is. Any options will be passed as widget arguments, see "widget" for details.
customwidget {
my $tbl = Tickit::Widget::Table::Paged->new;
$tbl->add_column(...);
$tbl;
} expand => 1;
widget
Many container widgets provide support for additional options when adding child widgets. For example, a Tickit::Widget::VBox can take an expand
parameter which determines how space should be allocated between children.
This function provides a way to pass those options - use it as a wrapper around another widget-generating function, like so:
widget { static 'this is text' } expand => 1;
in context, this would be:
vbox {
widget { static => '33%' } expand => 1;
widget { static => '66%' } expand => 2;
};
apply_widget
Internal function used for applying the given widget.
Not exported.
SEE ALSO
INHERITED METHODS
- Exporter
-
as_heavy, export, export_fail, export_ok_tags, export_tags, export_to_level, require_version
AUTHOR
Tom Molesworth <cpan@entitymodel.com>
LICENSE
Copyright Tom Molesworth 2012-2013. Licensed under the same terms as Perl itself.