Completed
Pull Request — master (#227)
by Aydin
05:18 queued 03:37
created

SelectableItemRenderer::render()   A

Complexity

Conditions 4
Paths 1

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 9
c 1
b 0
f 0
nc 1
nop 5
dl 0
loc 18
rs 9.9666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpSchool\CliMenu\MenuItem;
6
7
use PhpSchool\CliMenu\MenuStyle;
8
use PhpSchool\CliMenu\Style\ItemStyle;
9
use PhpSchool\CliMenu\Style\Selectable;
10
use PhpSchool\CliMenu\Util\StringUtil as s;
11
use function PhpSchool\CliMenu\Util\mapWithKeys;
12
13
class SelectableItemRenderer
14
{
15
    public function render(
16
        MenuStyle $menuStyle,
17
        Selectable $itemStyle,
18
        string $text,
19
        bool $selected,
20
        bool $disabled
21
    ) : array {
22
        $marker = $itemStyle->getMarker($selected);
23
        $availableTextWidth = $this->getAvailableTextWidth($menuStyle, $itemStyle);
24
25
        return mapWithKeys(
26
            $this->wrapAndIndentText($marker, $text, $availableTextWidth),
27
            function (int $key, string $row) use ($menuStyle, $itemStyle, $availableTextWidth, $disabled) {
28
                $text = $disabled ? $menuStyle->getDisabledItemText($row) : $row;
29
30
                return $key === 0 && $itemStyle->getDisplaysExtra()
31
                    ? $this->lineWithExtra($text, $availableTextWidth, $itemStyle)
32
                    : $text;
33
            }
34
        );
35
    }
36
37
    public function wrapAndIndentText(string $marker, string $text, int $availableWidth) : array
38
    {
39
        return explode(
40
            "\n",
41
            s::wordwrap(
42
                "{$marker}{$text}",
43
                $availableWidth,
44
                sprintf("\n%s", $this->emptyString(mb_strlen($marker)))
45
            )
46
        );
47
    }
48
49
    public function lineWithExtra(string $text, int $availableWidth, ItemStyle $itemStyle) : string
50
    {
51
        return sprintf(
52
            '%s%s  %s',
53
            $text,
54
            $this->emptyString($availableWidth - s::length($text)),
55
            $itemStyle->getItemExtra()
56
        );
57
    }
58
59
    public function emptyString(int $numCharacters) : string
60
    {
61
        return str_repeat(' ', $numCharacters);
62
    }
63
64
    public function getAvailableTextWidth(MenuStyle $menuStyle, ItemStyle $itemStyle) : int
65
    {
66
        return $itemStyle->getDisplaysExtra()
67
            ? $menuStyle->getContentWidth() - (mb_strlen($itemStyle->getItemExtra()) + 2)
68
            : $menuStyle->getContentWidth();
69
    }
70
}
71