Completed
Pull Request — master (#84)
by
unknown
01:53
created

SplitItem::getSelectedItemIndex()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
3
namespace PhpSchool\CliMenu\MenuItem;
4
5
use Assert\Assertion;
6
use PhpSchool\CliMenu\CliMenu;
7
use PhpSchool\CliMenu\MenuStyle;
8
use PhpSchool\CliMenu\Util\StringUtil;
9
10
/**
11
 * @author Michael Woodward <[email protected]>
12
 */
13
class SplitItem implements MenuItemInterface
14
{
15
    /**
16
     * @var string
17
     */
18
    private $text;
19
20
    /**
21
     * @var array
22
     */
23
    private $items;
24
25
    /**
26
     * @var int
27
     * -1 means no item selected
28
     */
29
    private $selectedItemIndex = -1;
30
31
    /**
32
     * @var int
33
     */
34
    private $margin = 2;
35
36
37
    public function __construct(string $text, array $items)
38
    {
39
        $this->text     = $text;
40
        $this->items    = $items;
41
    }
42
43
    /**
44
     * The output text for the item
45
     */
46
    public function getRows(MenuStyle $style, bool $selected = false) : array
47
    {
48
        $numberOfItems = count($this->items);
49
50
        if (!$selected) {
51
            $this->selectedItemIndex = -1;
52
        } else {
53
            if ($this->selectedItemIndex === -1) {
54
                $this->selectedItemIndex = 0;
55
            }
56
        }
57
58
        $length = $style->getDisplaysExtra()
59
            ? floor(($style->getContentWidth() - mb_strlen($style->getItemExtra()) + 2) / $numberOfItems) - $this->margin
60
            : floor($style->getContentWidth() / $numberOfItems) - $this->margin;
61
        $missingLength = $style->getContentWidth() % $numberOfItems;
62
63
        $lines = 0;
64
        $cells = [];
65
        foreach ($this->items as $index => $item) {
66
            $marker = sprintf("%s ", $style->getMarker($index === $this->selectedItemIndex));
67
            $content = StringUtil::wordwrap(
68
                sprintf('%s%s', $marker, $item->getText()),
69
                $length
70
            );
71
            $cell = array_map(function ($row) use ($index, $length, $style) {
72
                $row = $row . str_repeat(' ', $length - strlen($row));
73
                if ($index === $this->selectedItemIndex) {
74
                    $row = $style->getSelectedSetCode() . $row . $style->getSelectedUnsetCode();
75
                } else {
76
                    $row = $style->getUnselectedSetCode() . $row . $style->getUnselectedUnsetCode();
77
                }
78
                $row .= $style->getUnselectedSetCode() . str_repeat(' ', $this->margin);
79
                return $row;
80
            }, explode("\n", $content));
81
            $lineCount = count($cell);
82
            if ($lineCount > $lines) {
83
                $lines = $lineCount;
84
            }
85
            $cells[] = $cell;
86
        }
87
88
        $rows = [];
89
        for ($i = 0; $i < $lines; $i++) {
90
            $row = "";
91
            foreach ($cells as $cell) {
92
                if (isset($cell[$i])) {
93
                    $row .= $cell[$i];
94
                } else {
95
                    $row .= str_repeat(' ', $length);
96
                }
97
            }
98
            if ($missingLength) {
99
                $row .= str_repeat(' ', $missingLength);
100
            }
101
            $rows[] = $row;
102
        }
103
104
        return $rows;
105
    }
106
107
    /**
108
     *
109
     */
110
    public function setSelectedItemIndex(int $index) : void
111
    {
112
        $this->selectedItemIndex = $index;
113
    }
114
115
    /**
116
     *
117
     */
118
    public function getSelectedItemIndex() : int
119
    {
120
        if ($this->selectedItemIndex === -1) {
121
            return 0;
122
        }
123
        return $this->selectedItemIndex;
124
    }
125
    
126
    /**
127
     *
128
     */
129
    public function getItems() : array
130
    {
131
        return $this->items;
132
    }
133
134
    /**
135
     * Can the item be selected
136
     */
137
    public function canSelect() : bool
138
    {
139
        return true;
140
    }
141
142
    /**
143
     * Execute the items callable if required
144
     */
145
    public function getSelectAction() : ?callable
146
    {
147
        return null;
148
    }
149
150
    /**
151
     * Whether or not the menu item is showing the menustyle extra value
152
     */
153
    public function showsItemExtra() : bool
154
    {
155
        return false;
156
    }
157
158
    /**
159
     * Enable showing item extra
160
     */
161
    public function showItemExtra() : void
162
    {
163
        //noop
164
    }
165
166
    /**
167
     * Disable showing item extra
168
     */
169
    public function hideItemExtra() : void
170
    {
171
        //noop
172
    }
173
174
    /**
175
     * Return the raw string of text
176
     */
177
    public function getText() : string
178
    {
179
        return $this->text;
180
    }
181
}
182