Custom Widgets

Custom Widgets #

Widgets are composed of two parts:

  • An object containing the widget data implementing PhpTui\Tui\Widget\Widget.
  • A renderer for the widget implementing PhpTui\Tui\Widget\WidgetRenderer.

Separating these concerns allows the WidgetRenderer to have dependencies while the Widget will never have any.

Self Rendering Widgets #

Often widget renderers do not need dependencies, in which case the easier option is to have the Widget also implement WidgetRenderer:

<?php

declare(strict_types=1);

use PhpTui\Tui\Display\Area;
use PhpTui\Tui\Display\Buffer;
use PhpTui\Tui\DisplayBuilder;
use PhpTui\Tui\Position\Position;
use PhpTui\Tui\Widget\Widget;
use PhpTui\Tui\Widget\WidgetRenderer;

require 'vendor/autoload.php';

final class MyCustomWidget implements Widget, WidgetRenderer
{
    public function render(WidgetRenderer $renderer, Widget $widget, Buffer $buffer, Area $area): void
    {
        $buffer->putString(Position::at(0, 0), 'Hello World!');
    }
}

$display = DisplayBuilder::default()->build();
$display->draw(new MyCustomWidget());

Dedicated Renderer #

Alternatively you may want to inject a dependency, in which case you will need to register a renderer:

<?php

declare(strict_types=1);

use PhpTui\Tui\Display\Area;
use PhpTui\Tui\Display\Buffer;
use PhpTui\Tui\DisplayBuilder;
use PhpTui\Tui\Position\Position;
use PhpTui\Tui\Widget\Widget;
use PhpTui\Tui\Widget\WidgetRenderer;

require 'vendor/autoload.php';

final class MyCustomWidget implements Widget
{
}

final class MyCustomRenderer implements WidgetRenderer
{
    public function render(WidgetRenderer $renderer, Widget $widget, Buffer $buffer, Area $area): void
    {
        if (!$widget instanceof MyCustomWidget) {
            return;
        }

        $buffer->putString(Position::at(0, 0), 'Hello World!');
    }
}

$display = DisplayBuilder::default()
    ->addWidgetRenderer(new MyCustomRenderer())
    ->build();
$display->draw(new MyCustomWidget());