-
Notifications
You must be signed in to change notification settings - Fork 108
Closed
Description
Line 384 in 74dca3e
public function getSelectedItem() : MenuItemInterface |
If you have a group of MenuItem
in a SplitItem
calling CliMenu::getSelectedItem()
returns the actual MenuItem
, not the SplitItem
group. This is fine.
However, there is currently no way of fetching the SplitItem
group from within a callback:
<?php
use PhpSchool\CliMenu\Builder\SplitItemBuilder;
use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\MenuItem\CheckableItem;
require_once(__DIR__ . '/../vendor/autoload.php');
$itemCallable = function (CliMenu $menu) {
/** @var CheckableItem $item */
$item = $menu->getSelectedItem();
// Unable to access SplitItem from here
};
$menu = (new CliMenuBuilder)
->setTitle('Select a Language')
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->setGutter(5)
->addCheckableItem('Rust', $itemCallable)
->addCheckableItem('C++', $itemCallable)
->addCheckableItem('Go', $itemCallable)
->addCheckableItem('Java', $itemCallable)
->addCheckableItem('C', $itemCallable)
;
})
->build();
$menu->open();
If we add the following to CliMenu
we can work around this problem:
public function getSelectedSplitItem() : MenuItemInterface
{
if (null === $this->selectedItem) {
throw new \RuntimeException('No selected item');
}
return $this->items[$this->selectedItem];
}
and changing our code to reflect this:
<?php
use PhpSchool\CliMenu\Builder\SplitItemBuilder;
use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\MenuItem\CheckableItem;
use PhpSchool\CliMenu\MenuItem\SplitItem;
require_once(__DIR__ . '/../vendor/autoload.php');
$itemCallable = function (CliMenu $menu) {
/** @var CheckableItem $selected */
$selected = $menu->getSelectedItem();
/** @var SplitItem $splitGroup */
$splitGroup = $menu->getSelectedSplitItem();
$selected->toggle();
/** @var CheckableItem $item */
foreach ($splitGroup->getItems() as $item) {
if (!is_a($item, CheckableItem::class)) {
continue;
}
if ($item === $selected) {
continue;
}
$item->setUnchecked();
}
$menu->redraw();
};
$menu = (new CliMenuBuilder)
->setTitle('Select a Language')
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->setGutter(5)
->addCheckableItem('Rust', $itemCallable)
->addCheckableItem('C++', $itemCallable)
->addCheckableItem('Go', $itemCallable)
->addCheckableItem('Java', $itemCallable)
->addCheckableItem('C', $itemCallable)
;
})
->build();
$menu->open();
results in radio-style elements:
Thoughts?
edit: Adding CheckableItem
via SplitItemBuilder
is part of PR #189.
This issue that you are reading now deals with being able to group items together by fetching SplitItem
from CliMenu
. It can also be applied to normal SelectableItem
.
Metadata
Metadata
Assignees
Labels
No labels