Skip to content

Commit 4a0bb52

Browse files
authored
Merge pull request #216 from jtreminio/feature/selectable-style
Finalize SelectableStyle for items
2 parents 4992019 + 16f56b8 commit 4a0bb52

File tree

11 files changed

+224
-254
lines changed

11 files changed

+224
-254
lines changed

examples/draw.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpSchool\CliMenu\CliMenu;
66
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
77
use PhpSchool\CliMenu\MenuItem\SplitItem;
8+
use PhpSchool\CliMenu\Style\SelectableStyle;
89

910
require_once(__DIR__ . '/../vendor/autoload.php');
1011

@@ -39,8 +40,10 @@
3940
->setBorder(0)
4041
->setMargin(2)
4142
->setPadding(2, 5)
42-
->setSelectedMarker('')
43-
->setUnselectedMarker('')
43+
->modifySelectableStyle(function (SelectableStyle $style) {
44+
$style->setSelectedMarker('')
45+
->setUnselectedMarker('');
46+
})
4447
->addAsciiArt('Draw your own art !')
4548
->addLineBreak();
4649

src/Builder/CliMenuBuilder.php

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -394,22 +394,6 @@ public function setMargin(int $margin) : self
394394
return $this;
395395
}
396396

397-
public function setUnselectedMarker(string $marker) : self
398-
{
399-
$this->style->setUnselectedMarker($marker);
400-
$this->menu->getSelectableStyle()->setUnselectedMarker($marker);
401-
402-
return $this;
403-
}
404-
405-
public function setSelectedMarker(string $marker) : self
406-
{
407-
$this->style->setSelectedMarker($marker);
408-
$this->menu->getSelectableStyle()->setSelectedMarker($marker);
409-
410-
return $this;
411-
}
412-
413397
public function setItemExtra(string $extra) : self
414398
{
415399
$this->style->setItemExtra($extra);
@@ -608,7 +592,10 @@ private function propagateStyles(CliMenu $menu, array $items = [])
608592
$item->setStyle(clone $menu->getRadioStyle());
609593
}
610594

611-
if ($item instanceof SelectableItem
595+
if (($item instanceof MenuMenuItem
596+
|| $item instanceof SelectableItem
597+
|| $item instanceof StaticItem
598+
)
612599
&& !$item->getStyle()->hasChangedFromDefaults()
613600
) {
614601
$item->setStyle(clone $menu->getSelectableStyle());

src/MenuItem/MenuMenuItem.php

Lines changed: 100 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,80 @@
22

33
namespace PhpSchool\CliMenu\MenuItem;
44

5-
use Assert\Assertion;
65
use PhpSchool\CliMenu\CliMenu;
6+
use PhpSchool\CliMenu\MenuStyle;
7+
use PhpSchool\CliMenu\Util\StringUtil;
8+
use PhpSchool\CliMenu\Style\SelectableStyle;
79

810
/**
911
* @author Michael Woodward <[email protected]>
1012
*/
1113
class MenuMenuItem implements MenuItemInterface
1214
{
13-
use SelectableTrait;
15+
private $text = '';
16+
17+
private $showItemExtra = false;
18+
19+
private $disabled = false;
20+
21+
/**
22+
* @var SelectableStyle;
23+
*/
24+
private $style;
1425

1526
/**
1627
* @var CliMenu
1728
*/
1829
private $subMenu;
1930

20-
public function __construct(string $text, CliMenu $subMenu, bool $disabled = false)
21-
{
31+
public function __construct(
32+
string $text,
33+
CliMenu $subMenu,
34+
bool $disabled = false
35+
) {
2236
$this->text = $text;
2337
$this->subMenu = $subMenu;
2438
$this->disabled = $disabled;
39+
40+
$this->style = new SelectableStyle();
41+
}
42+
43+
/**
44+
* The output text for the item
45+
*/
46+
public function getRows(MenuStyle $style, bool $selected = false) : array
47+
{
48+
$marker = sprintf("%s", $this->style->getMarker($selected));
49+
50+
$length = $this->style->getDisplaysExtra()
51+
? $style->getContentWidth() - (mb_strlen($this->style->getItemExtra()) + 2)
52+
: $style->getContentWidth();
53+
54+
$rows = explode(
55+
"\n",
56+
StringUtil::wordwrap(
57+
sprintf('%s%s', $marker, $this->text),
58+
$length,
59+
sprintf("\n%s", str_repeat(' ', mb_strlen($marker)))
60+
)
61+
);
62+
63+
return array_map(function ($row, $key) use ($style, $length) {
64+
$text = $this->disabled ? $style->getDisabledItemText($row) : $row;
65+
66+
if ($key === 0) {
67+
return $this->showItemExtra
68+
? sprintf(
69+
'%s%s %s',
70+
$text,
71+
str_repeat(' ', $length - mb_strlen($row)),
72+
$this->style->getItemExtra()
73+
)
74+
: $text;
75+
}
76+
77+
return $text;
78+
}, $rows, array_keys($rows));
2579
}
2680

2781
/**
@@ -34,6 +88,18 @@ public function getSelectAction() : ?callable
3488
};
3589
}
3690

91+
public function getStyle() : SelectableStyle
92+
{
93+
return $this->style;
94+
}
95+
96+
public function setStyle(SelectableStyle $style) : self
97+
{
98+
$this->style = $style;
99+
100+
return $this;
101+
}
102+
37103
/**
38104
* Return the raw string of text
39105
*/
@@ -49,7 +115,36 @@ public function setText(string $text) : void
49115
{
50116
$this->text = $text;
51117
}
52-
118+
119+
/**
120+
* Can the item be selected
121+
*/
122+
public function canSelect() : bool
123+
{
124+
return !$this->disabled;
125+
}
126+
127+
public function showsItemExtra() : bool
128+
{
129+
return $this->showItemExtra;
130+
}
131+
132+
/**
133+
* Enable showing item extra
134+
*/
135+
public function showItemExtra() : void
136+
{
137+
$this->showItemExtra = true;
138+
}
139+
140+
/**
141+
* Disable showing item extra
142+
*/
143+
public function hideItemExtra() : void
144+
{
145+
$this->showItemExtra = false;
146+
}
147+
53148
/**
54149
* Returns the sub menu
55150
*/

src/MenuItem/SelectableTrait.php

Lines changed: 0 additions & 89 deletions
This file was deleted.

src/MenuItem/SplitItem.php

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -117,35 +117,35 @@ public function getRows(MenuStyle $style, bool $selected = false) : array
117117
$this->setDefaultSelectedItem();
118118
}
119119

120-
$length = $style->getDisplaysExtra()
121-
? floor($style->getContentWidth() / $numberOfItems) - (mb_strlen($style->getItemExtra()) + 2)
120+
$largestItemExtra = $this->calculateItemExtra();
121+
122+
$length = $largestItemExtra > 0
123+
? floor($style->getContentWidth() / $numberOfItems) - ($largestItemExtra + 2)
122124
: floor($style->getContentWidth() / $numberOfItems);
123-
125+
124126
$length -= $this->gutter;
125127
$length = (int) $length;
126-
128+
127129
$missingLength = $style->getContentWidth() % $numberOfItems;
128130

129131
return $this->buildRows(
130132
array_map(function ($index, $item) use ($selected, $length, $style) {
131133
$isSelected = $selected && $index === $this->selectedItemIndex;
132134

133135
if ($item instanceof CheckboxItem || $item instanceof RadioItem) {
134-
$markerType = $item->getStyle()->getMarker($item->getChecked());
135-
$displaysExtra = $item->getStyle()->getDisplaysExtra();
136-
$itemExtraVal = $item->getStyle()->getItemExtra();
136+
$markerType = $item->getStyle()->getMarker($item->getChecked());
137137
} else {
138-
$markerType = $style->getMarker($isSelected);
139-
$displaysExtra = $style->getDisplaysExtra();
140-
$itemExtraVal = $style->getItemExtra();
138+
/** @var MenuMenuItem|SelectableItem|StaticItem $item */
139+
$markerType = $item->getStyle()->getMarker($isSelected);
141140
}
142141

143142
$marker = $item->canSelect()
144143
? sprintf('%s', $markerType)
145144
: '';
146145

147146
$itemExtra = '';
148-
if ($displaysExtra) {
147+
if ($item->getStyle()->getDisplaysExtra()) {
148+
$itemExtraVal = $item->getStyle()->getItemExtra();
149149
$itemExtra = $item->showsItemExtra()
150150
? sprintf(' %s', $itemExtraVal)
151151
: sprintf(' %s', str_repeat(' ', mb_strlen($itemExtraVal)));
@@ -166,15 +166,15 @@ public function getRows(MenuStyle $style, bool $selected = false) : array
166166
$itemExtra
167167
);
168168
}, array_keys($this->items), $this->items),
169-
$style,
170169
$missingLength,
171-
$length
170+
$length,
171+
$largestItemExtra
172172
);
173173
}
174174

175-
private function buildRows(array $cells, MenuStyle $style, int $missingLength, int $length) : array
175+
private function buildRows(array $cells, int $missingLength, int $length, int $largestItemExtra) : array
176176
{
177-
$extraPadLength = $style->getDisplaysExtra() ? 2 + mb_strlen($style->getItemExtra()) : 0;
177+
$extraPadLength = $largestItemExtra > 0 ? 2 + $largestItemExtra : 0;
178178

179179
return array_map(
180180
function ($i) use ($cells, $length, $missingLength, $extraPadLength) {
@@ -325,4 +325,27 @@ public function getText() : string
325325
{
326326
throw new \BadMethodCallException(sprintf('Not supported on: %s', __CLASS__));
327327
}
328+
329+
/**
330+
* Finds largest itemExtra value in items
331+
*/
332+
private function calculateItemExtra() : int
333+
{
334+
$largestItemExtra = 0;
335+
336+
/** @var CheckboxItem|RadioItem|MenuMenuItem|SelectableItem|StaticItem $item */
337+
foreach ($this->items as $item) {
338+
if (!$item->getStyle()->getDisplaysExtra()) {
339+
continue;
340+
}
341+
342+
if (mb_strlen($item->getStyle()->getItemExtra()) < $largestItemExtra) {
343+
continue;
344+
}
345+
346+
$largestItemExtra = mb_strlen($item->getStyle()->getItemExtra());
347+
}
348+
349+
return $largestItemExtra;
350+
}
328351
}

0 commit comments

Comments
 (0)