=for comment POD_DERIVED_INDEX_GENERATED
The following documentation is automatically generated.  Please do not edit
this file, but rather the original, inline with Tickit::Widget::Tree
at lib/Tickit/Widget/Tree.pm
(on the system that originally ran this).
If you do edit this file, and don't want your changes to be removed, make
sure you change the first line.

=encoding utf8

=cut

=head1 NAME

Tickit::Widget::Tree - tree widget implementation for L<Tickit>

=head1 VERSION

version 0.114

=head1 SYNOPSIS

 use Tickit::Widget::Tree;
 my $tree = Tickit::Widget::Tree->new(root => Tree::DAG_Node->new);

=head1 DESCRIPTION

B<NOTE>: Versions 0.003 and below used a custom graph management
implementation which had various problems with rendering glitches
and performance. This version has been rewritten from scratch to
use L<Tree::DAG_Node> to handle the tree structure, and as such
is not backward compatible.

=begin HTML

<p><img src="http://tickit.perlsite.co.uk/cpan-screenshot/tickit-widget-tree1.gif" alt="Tree widget in action" width="480" height="403"></p>

=end HTML

=head1 STYLES

The following style keys are recognised, in addition to base styling
which will be applied to the tree lines:

=over 4

=item * line_style - which line type to use, default 'single', other
options include 'thick' or 'double'

=item * expand_style - 'boxed' is the only option for now, to select
a Unicode +/- boxed icon

=item * highlight_(fg|bg|b|rv) - highlight styling

=item * highlight_full_row - if true, will apply highlighting to the
entire width of the widget, rather than just the text

=back

=begin HTML

<p><img src="http://tickit.perlsite.co.uk/cpan-screenshot/tickit-widget-tree2.png" alt="Tree widget styles" width="302" height="249"></p>

=end HTML

Key bindings are currently:

=over 4

=item * previous_row - move up a line, stepping into open nodes, default C<Up>

=item * next_row - move down a line, stepping into open nodes, default C<Down>

=item * up_tree - move to the parent, default C<Left>

=item * down_tree - move to the first child, opening the current node if
necessary, default C<Right>

=item * open_node - opens the current node, default C<+>

=item * close_node - closes the current node, default C<->

=item * activate - activates the current node, default C<Enter>

=item * first_row - jump to the first node in the tree, default C<Home>

=item * last_row - jump to the last node in the tree, default C<End>

=back

=head2 calculate_size

Calculate the minimum size needed to contain the full tree with all nodes expanded.

Used internally.

=head2 new

Instantiate. Takes the following named parameters:

=over 4

=item * root - the root L<Tree::DAG_Node>

=item * on_activate - coderef to call when a node has been activated (usually
via 'enter' keypress)

=item * data - if provided, this will be used as a data structure to build the initial tree.

=back

Example usage:

 Tickit:Widget::Tree->new(
  data => [
 	node1 => [
		qw(some nodes here)
	],
	node2 => [
		qw(more nodes in this one),
		and => [
			qw(this has a few child nodes too)
		]
	],
  ];
 );

You can get "live" nodes by attaching an L<Adapter::Async::OrderedList> instance:

 Tickit:Widget::Tree->new(
  data => [
    live => my $adapter = Adapter::Async::OrderedList::Array->new(data => [ ]),
 	static => [
		qw(some static nodes here that will not change)
	],
  ];
 );
 ( # and this is where the magic happens...
  Future::Utils::repeat {
   my $item = shift;
   $loop->delay_future(
    after => 0.5
   )->then(sub {
    $adapter->push([ $item ]) 
   })
  } foreach => [qw(live changes work like this)]
 )->get;

Normally the adapter would come from somewhere else - database cursor, L<Tangence> property,
etc. - rather than being instantiated in-place like this. See C< examples/adapter.pl > for
a simple example of a manually-driven adapter.

=head2 add_item_under_parent

Adds the given item under a parent node.

Takes the following parameters:

=over 4

=item * $parent - which L<Tree::DAG_Node> to add this item to

=item * $item - a thing to add

=back

Currently this supports:

=over 4

=item * plain strings - will be used directly as the node label

=item * L<String::Tagged> instances - used as the node label, standard formatting (b/fg/bg)

=item * arrayrefs

=item * L<Adapter::Async::OrderedList> instances - "live" nodes that autoupdate

=back

Probably returns the $node that was just added, but don't count on it.

=head2 nodes_from_data

Given a scalar:

=over 4

=item * $item - a thing to add

=back

this will generate zero or more nodes that can be added to the tree.

Currently this supports:

=over 4

=item * plain strings - will be used directly as the node label

=item * L<String::Tagged> instances - used as the node label, standard formatting (b/fg/bg)

=item * arrayrefs -

=item * hashrefs - one text node will be created for each key, using the key as the name, and the content will be generated recursively using this method again

=item * L<Adapter::Async::OrderedList> instances - "live" nodes that autoupdate

=back

Probably returns the $node that was just added, but don't count on it.

=head2 root

Accessor for the root node. If given a parameter, will set the root node accordingly (and
mark the tree for redraw), returning $self.

Otherwise, returns the root node - or undef if we do not have one.

=head2 window_gained

Work out our size, when we have a window to fit in.

=head2 set_scrolling_extents

Called by L<Tickit::Widget::ScrollBox> or other scroll-capable containers to
set up the extent objects which determine the drawable viewport offset.

=head2 scrolled

Called by L<Tickit::Widget::ScrollBox> or other scroll-capable containers to
indicate when scroll actions have occurred.

=head2 render_to_rb

Render method. Used internally.

=head2 adapter_for_node

Returns or sets an L<Adapter::Async::OrderedList> for the given node.

This is the primary mechanism for making a node "live" - once it has been
attached to an adapter, the child nodes will update according to events on
the adapter.

 $node = $tree->node;
 $node->adapter_for_node->push([1,2,3]);

=head2 position_adapter

Returns the "position" adapter. This is an L<Adapter::Async::OrderedList::Array>
indicating where we are in the tree - it's a list of all the nodes leading to
the currently-highlighted one.

Note that this will return L<Tree::DAG_Node> items. You'd probably want the L<Tree::DAG_Node/name>
method to get something printable.

Example usage:

 my $tree = Tickit::Widget::Tree->new(...);
 my $where_am_i = Tickit::Widget::Breadcrumb->new(
  item_transformations => sub {
   shift->name
  }
 );
 $where_am_i->adapter($tree->position_adapter);

=head2 reshape

Workaround to avoid warnings from L<Tickit::Window>. This probably shouldn't
be here, pretend you didn't see it.

=head2 on_mouse

Mouse callback. Used internally.

=head2 key_first_row

Jump to the first row. Normally bound to the C<Home> key.

=head2 key_last_row

Jump to the last row. Normally bound to the C<End> key.

=head2 key_previous_row

Go up a node.

=head2 key_next_row

Move down a node.

=head2 key_up_tree

Going "up" the tree means the parent of the current node.

=head2 key_down_tree

Going "down" the tree means the first child node, if we have one
and we're open.

=head2 highlight_node

Change the currently highlighted node.

=head2 key_open_node

Open this node.

=head2 key_close_node

Close this node.

=head2 key_activate

Call the C<on_activate> coderef if we have it.

=head1 TODO

Plenty of features and bugfixes left on the list, in no particular order:

=over 4

=item * Avoid full redraw when moving highlight or opening/closing nodes

=item * Support nested widgets

=item * Node reordering

=item * Detect changes to the underlying L<Tree::DAG_Node> structure

=back

=head1 INHERITED METHODS

=over 4

=item L<Tickit::Widget>

L<get_style_pen|Tickit::Widget/get_style_pen>, L<get_style_text|Tickit::Widget/get_style_text>, L<get_style_values|Tickit::Widget/get_style_values>, L<key_focus_next_after|Tickit::Widget/key_focus_next_after>, L<key_focus_next_before|Tickit::Widget/key_focus_next_before>, L<on_pen_changed|Tickit::Widget/on_pen_changed>, L<parent|Tickit::Widget/parent>, L<pen|Tickit::Widget/pen>, L<redraw|Tickit::Widget/redraw>, L<requested_cols|Tickit::Widget/requested_cols>, L<requested_lines|Tickit::Widget/requested_lines>, L<requested_size|Tickit::Widget/requested_size>, L<resized|Tickit::Widget/resized>, L<set_parent|Tickit::Widget/set_parent>, L<set_pen|Tickit::Widget/set_pen>, L<set_requested_size|Tickit::Widget/set_requested_size>, L<set_style|Tickit::Widget/set_style>, L<set_style_tag|Tickit::Widget/set_style_tag>, L<set_window|Tickit::Widget/set_window>, L<style_classes|Tickit::Widget/style_classes>, L<take_focus|Tickit::Widget/take_focus>, L<window|Tickit::Widget/window>, L<window_lost|Tickit::Widget/window_lost>

=item L<Mixin::Event::Dispatch>

L<add_handler_for_event|Mixin::Event::Dispatch/add_handler_for_event>, L<clear_event_handlers|Mixin::Event::Dispatch/clear_event_handlers>, L<event_handlers|Mixin::Event::Dispatch/event_handlers>, L<invoke_event|Mixin::Event::Dispatch/invoke_event>, L<subscribe_to_event|Mixin::Event::Dispatch/subscribe_to_event>, L<unsubscribe_from_event|Mixin::Event::Dispatch/unsubscribe_from_event>

=back

=head1 AUTHOR

Tom Molesworth <cpan@perlsite.co.uk>

=head1 LICENSE

Copyright Tom Molesworth 2011-2015. Licensed under the same terms as Perl itself.
