diff --git a/README.md b/README.md index 8af5be97..dc5e1ef4 100644 --- a/README.md +++ b/README.md @@ -817,10 +817,13 @@ You may also change the marker for `\PhpSchool\CliMenu\MenuItem\CheckboxItem`: setUncheckedMarker('[○] ') - ->setCheckedMarker('[●] ') + ->modifyCheckboxStyle(function (CheckboxStyle $style) { + $style->setMarkerOff('[○] ') + ->setMarkerOn('[●] '); + }) ->build(); ``` @@ -830,10 +833,13 @@ and for `\PhpSchool\CliMenu\MenuItem\RadioItem`: setUnradioMarker('[ ] ') - ->setRadioMarker('[✔] ') + ->modifyRadioStyle(function (RadioStyle $style) { + $style->setMarkerOff('[ ] ') + ->setMarkerOn('[✔] '); + }) ->build(); ``` diff --git a/examples/checkable-item.php b/examples/checkbox-item.php similarity index 83% rename from examples/checkable-item.php rename to examples/checkbox-item.php index 75618775..09d65860 100644 --- a/examples/checkable-item.php +++ b/examples/checkbox-item.php @@ -2,6 +2,7 @@ use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\Builder\CliMenuBuilder; +use PhpSchool\CliMenu\Style\CheckboxStyle; require_once(__DIR__ . '/../vendor/autoload.php'); @@ -22,8 +23,10 @@ }) ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use ($itemCallable) { $b->setTitle('Interpreted Languages') - ->setUncheckedMarker('[○] ') - ->setCheckedMarker('[●] ') + ->modifyCheckboxStyle(function (CheckboxStyle $style) { + $style->setMarkerOff('[○] ') + ->setMarkerOn('[●] '); + }) ->addCheckboxItem('PHP', $itemCallable) ->addCheckboxItem('Javascript', $itemCallable) ->addCheckboxItem('Ruby', $itemCallable) diff --git a/examples/radio-item.php b/examples/radio-item.php index d3b7f0c9..7f7ff5ff 100644 --- a/examples/radio-item.php +++ b/examples/radio-item.php @@ -2,6 +2,7 @@ use PhpSchool\CliMenu\CliMenu; use PhpSchool\CliMenu\Builder\CliMenuBuilder; +use PhpSchool\CliMenu\Style\RadioStyle; require_once(__DIR__ . '/../vendor/autoload.php'); @@ -22,8 +23,10 @@ }) ->addSubMenu('Interpreted', function (CliMenuBuilder $b) use ($itemCallable) { $b->setTitle('Interpreted Languages') - ->setUnradioMarker('[ ] ') - ->setRadioMarker('[✔] ') + ->modifyRadioStyle(function (RadioStyle $style) { + $style->setMarkerOff('[ ] ') + ->setMarkerOn('[✔] '); + }) ->addRadioItem('PHP', $itemCallable) ->addRadioItem('Javascript', $itemCallable) ->addRadioItem('Ruby', $itemCallable) diff --git a/examples/split-checkable-item.php b/examples/split-checkbox-item.php similarity index 100% rename from examples/split-checkable-item.php rename to examples/split-checkbox-item.php diff --git a/src/Builder/CliMenuBuilder.php b/src/Builder/CliMenuBuilder.php index 5edd7a4e..1ea00682 100644 --- a/src/Builder/CliMenuBuilder.php +++ b/src/Builder/CliMenuBuilder.php @@ -16,6 +16,8 @@ use PhpSchool\CliMenu\MenuItem\SplitItem; use PhpSchool\CliMenu\MenuItem\StaticItem; use PhpSchool\CliMenu\MenuStyle; +use PhpSchool\CliMenu\Style\CheckboxStyle; +use PhpSchool\CliMenu\Style\RadioStyle; use PhpSchool\CliMenu\Terminal\TerminalFactory; use PhpSchool\Terminal\Terminal; @@ -187,7 +189,7 @@ public function addSubMenu(string $text, \Closure $callback) : self $menu = $builder->build(); $menu->setParent($this->menu); - + $this->menu->addItem($item = new MenuMenuItem( $text, $menu, @@ -290,7 +292,7 @@ public function addSplitItem(\Closure $callback) : self } $callback($builder); - + $this->menu->addItem($splitItem = $builder->build()); $this->processSplitItemShortcuts($splitItem); @@ -405,34 +407,6 @@ public function setSelectedMarker(string $marker) : self return $this; } - public function setUncheckedMarker(string $marker) : self - { - $this->style->setUncheckedMarker($marker); - - return $this; - } - - public function setCheckedMarker(string $marker) : self - { - $this->style->setCheckedMarker($marker); - - return $this; - } - - public function setUnradioMarker(string $marker) : self - { - $this->style->setUnradioMarker($marker); - - return $this; - } - - public function setRadioMarker(string $marker) : self - { - $this->style->setRadioMarker($marker); - - return $this; - } - public function setItemExtra(string $extra) : self { $this->style->setItemExtra($extra); @@ -551,6 +525,44 @@ public function build() : CliMenu return $this->menu; } + public function getCheckboxStyle() : CheckboxStyle + { + return $this->menu->getCheckboxStyle(); + } + + public function setCheckboxStyle(CheckboxStyle $style) : self + { + $this->menu->setCheckboxStyle($style); + + return $this; + } + + public function modifyCheckboxStyle(callable $itemCallable) : self + { + $itemCallable($this->menu->getCheckboxStyle()); + + return $this; + } + + public function getRadioStyle() : RadioStyle + { + return $this->menu->getRadioStyle(); + } + + public function setRadioStyle(RadioStyle $style) : self + { + $this->menu->setRadioStyle($style); + + return $this; + } + + public function modifyRadioStyle(callable $itemCallable) : self + { + $itemCallable($this->menu->getRadioStyle()); + + return $this; + } + /** * Pass styles from current menu to sub-menu * only if sub-menu style has not be customized @@ -560,6 +572,18 @@ private function propagateStyles(CliMenu $menu, array $items = []) $currentItems = !empty($items) ? $items : $menu->getItems(); foreach ($currentItems as $item) { + if ($item instanceof CheckboxItem + && !$item->getStyle()->hasChangedFromDefaults() + ) { + $item->setStyle(clone $menu->getCheckboxStyle()); + } + + if ($item instanceof RadioItem + && !$item->getStyle()->hasChangedFromDefaults() + ) { + $item->setStyle(clone $menu->getRadioStyle()); + } + // Apply current style to children, if they are not customized if ($item instanceof MenuMenuItem) { $subMenu = $item->getSubMenu(); @@ -568,6 +592,14 @@ private function propagateStyles(CliMenu $menu, array $items = []) $subMenu->setStyle(clone $menu->getStyle()); } + if (!$subMenu->getCheckboxStyle()->hasChangedFromDefaults()) { + $subMenu->setCheckboxStyle(clone $menu->getCheckboxStyle()); + } + + if (!$subMenu->getRadioStyle()->hasChangedFromDefaults()) { + $subMenu->setRadioStyle(clone $menu->getRadioStyle()); + } + $this->propagateStyles($subMenu); } diff --git a/src/Builder/SplitItemBuilder.php b/src/Builder/SplitItemBuilder.php index c5da6531..dfca5189 100644 --- a/src/Builder/SplitItemBuilder.php +++ b/src/Builder/SplitItemBuilder.php @@ -113,14 +113,14 @@ public function addSubMenu(string $text, \Closure $callback) : self $menu, $builder->isMenuDisabled() )); - + return $this; } public function setGutter(int $gutter) : self { $this->splitItem->setGutter($gutter); - + return $this; } @@ -134,7 +134,7 @@ public function enableAutoShortcuts(string $regex = null) : self return $this; } - + public function build() : SplitItem { return $this->splitItem; diff --git a/src/CliMenu.php b/src/CliMenu.php index 5b7631ba..1a15bc08 100644 --- a/src/CliMenu.php +++ b/src/CliMenu.php @@ -14,6 +14,8 @@ use PhpSchool\CliMenu\MenuItem\StaticItem; use PhpSchool\CliMenu\Dialogue\Confirm; use PhpSchool\CliMenu\Dialogue\Flash; +use PhpSchool\CliMenu\Style\CheckboxStyle; +use PhpSchool\CliMenu\Style\RadioStyle; use PhpSchool\CliMenu\Terminal\TerminalFactory; use PhpSchool\CliMenu\Util\StringUtil as s; use PhpSchool\Terminal\InputCharacter; @@ -35,6 +37,16 @@ class CliMenu */ protected $style; + /** + * @var CheckboxStyle + */ + private $checkboxStyle; + + /** + * @var RadioStyle + */ + private $radioStyle; + /** * @var ?string */ @@ -90,10 +102,12 @@ public function __construct( Terminal $terminal = null, MenuStyle $style = null ) { - $this->title = $title; - $this->items = $items; - $this->terminal = $terminal ?: TerminalFactory::fromSystem(); - $this->style = $style ?: new MenuStyle($this->terminal); + $this->title = $title; + $this->items = $items; + $this->terminal = $terminal ?: TerminalFactory::fromSystem(); + $this->style = $style ?: new MenuStyle($this->terminal); + $this->checkboxStyle = new CheckboxStyle(); + $this->radioStyle = new RadioStyle(); $this->selectFirstItem(); } @@ -640,6 +654,30 @@ public function setStyle(MenuStyle $style) : void $this->style = $style; } + public function getCheckboxStyle() : CheckboxStyle + { + return $this->checkboxStyle; + } + + public function setCheckboxStyle(CheckboxStyle $style) : self + { + $this->checkboxStyle = $style; + + return $this; + } + + public function getRadioStyle() : RadioStyle + { + return $this->radioStyle; + } + + public function setRadioStyle(RadioStyle $style) : self + { + $this->radioStyle = $style; + + return $this; + } + public function getCurrentFrame() : Frame { return $this->currentFrame; diff --git a/src/MenuItem/CheckboxItem.php b/src/MenuItem/CheckboxItem.php index f0278bbf..be2b3398 100644 --- a/src/MenuItem/CheckboxItem.php +++ b/src/MenuItem/CheckboxItem.php @@ -3,30 +3,29 @@ namespace PhpSchool\CliMenu\MenuItem; use PhpSchool\CliMenu\CliMenu; +use PhpSchool\CliMenu\MenuStyle; +use PhpSchool\CliMenu\Util\StringUtil; +use PhpSchool\CliMenu\Style\CheckboxStyle; class CheckboxItem implements MenuItemInterface, ToggableItemInterface { - use ToggableTrait; - /** * @var callable */ private $selectAction; - /** - * @var string - */ private $text = ''; - /** - * @var bool - */ private $showItemExtra = false; + private $disabled = false; + + private $checked = false; + /** - * @var bool + * @var CheckboxStyle; */ - private $disabled = false; + private $style; public function __construct( string $text, @@ -38,6 +37,43 @@ public function __construct( $this->selectAction = $selectAction; $this->showItemExtra = $showItemExtra; $this->disabled = $disabled; + + $this->style = new CheckboxStyle(); + } + + /** + * The output text for the item + */ + public function getRows(MenuStyle $style, bool $selected = false) : array + { + $marker = sprintf("%s", $this->style->getMarker($this->checked)); + + $itemExtra = $this->style->getItemExtra(); + + $length = $this->style->getDisplaysExtra() + ? $style->getContentWidth() - (mb_strlen($itemExtra) + 2) + : $style->getContentWidth(); + + $rows = explode( + "\n", + StringUtil::wordwrap( + sprintf('%s%s', $marker, $this->text), + $length, + sprintf("\n%s", str_repeat(' ', mb_strlen($marker))) + ) + ); + + return array_map(function ($row, $key) use ($style, $length, $itemExtra) { + $text = $this->disabled ? $style->getDisabledItemText($row) : $row; + + if ($key === 0) { + return $this->showItemExtra + ? sprintf('%s%s %s', $text, str_repeat(' ', $length - mb_strlen($row)), $itemExtra) + : $text; + } + + return $text; + }, $rows, array_keys($rows)); } /** @@ -53,6 +89,50 @@ public function getSelectAction() : ?callable }; } + public function getStyle() : CheckboxStyle + { + return $this->style; + } + + public function setStyle(CheckboxStyle $style) : self + { + $this->style = $style; + + return $this; + } + + /** + * Toggles checked state + */ + public function toggle() : void + { + $this->checked = !$this->checked; + } + + /** + * Sets checked state to true + */ + public function setChecked() : void + { + $this->checked = true; + } + + /** + * Sets checked state to false + */ + public function setUnchecked() : void + { + $this->checked = false; + } + + /** + * Whether or not the item is checked + */ + public function getChecked() : bool + { + return $this->checked; + } + /** * Return the raw string of text */ diff --git a/src/MenuItem/RadioItem.php b/src/MenuItem/RadioItem.php index d4129699..d6017d60 100644 --- a/src/MenuItem/RadioItem.php +++ b/src/MenuItem/RadioItem.php @@ -3,30 +3,29 @@ namespace PhpSchool\CliMenu\MenuItem; use PhpSchool\CliMenu\CliMenu; +use PhpSchool\CliMenu\MenuStyle; +use PhpSchool\CliMenu\Util\StringUtil; +use PhpSchool\CliMenu\Style\RadioStyle; class RadioItem implements MenuItemInterface, ToggableItemInterface { - use ToggableTrait; - /** * @var callable */ private $selectAction; - /** - * @var string - */ private $text = ''; - /** - * @var bool - */ private $showItemExtra = false; + private $disabled = false; + + private $checked = false; + /** - * @var bool + * @var RadioStyle; */ - private $disabled = false; + private $style; public function __construct( string $text, @@ -38,6 +37,43 @@ public function __construct( $this->selectAction = $selectAction; $this->showItemExtra = $showItemExtra; $this->disabled = $disabled; + + $this->style = new RadioStyle(); + } + + /** + * The output text for the item + */ + public function getRows(MenuStyle $style, bool $selected = false) : array + { + $marker = sprintf("%s", $this->style->getMarker($this->checked)); + + $itemExtra = $this->style->getItemExtra(); + + $length = $this->style->getDisplaysExtra() + ? $style->getContentWidth() - (mb_strlen($itemExtra) + 2) + : $style->getContentWidth(); + + $rows = explode( + "\n", + StringUtil::wordwrap( + sprintf('%s%s', $marker, $this->text), + $length, + sprintf("\n%s", str_repeat(' ', mb_strlen($marker))) + ) + ); + + return array_map(function ($row, $key) use ($style, $length, $itemExtra) { + $text = $this->disabled ? $style->getDisabledItemText($row) : $row; + + if ($key === 0) { + return $this->showItemExtra + ? sprintf('%s%s %s', $text, str_repeat(' ', $length - mb_strlen($row)), $itemExtra) + : $text; + } + + return $text; + }, $rows, array_keys($rows)); } /** @@ -73,6 +109,50 @@ function (RadioItem $item) { }; } + public function getStyle() : RadioStyle + { + return $this->style; + } + + public function setStyle(RadioStyle $style) : self + { + $this->style = $style; + + return $this; + } + + /** + * Toggles checked state + */ + public function toggle() : void + { + $this->checked = !$this->checked; + } + + /** + * Sets checked state to true + */ + public function setChecked() : void + { + $this->checked = true; + } + + /** + * Sets checked state to false + */ + public function setUnchecked() : void + { + $this->checked = false; + } + + /** + * Whether or not the item is checked + */ + public function getChecked() : bool + { + return $this->checked; + } + /** * Return the raw string of text */ diff --git a/src/MenuItem/SplitItem.php b/src/MenuItem/SplitItem.php index 6369d8fe..cca5a999 100644 --- a/src/MenuItem/SplitItem.php +++ b/src/MenuItem/SplitItem.php @@ -130,16 +130,14 @@ public function getRows(MenuStyle $style, bool $selected = false) : array array_map(function ($index, $item) use ($selected, $length, $style) { $isSelected = $selected && $index === $this->selectedItemIndex; - if ($item instanceof CheckboxItem) { - $markerType = $item->getChecked() - ? $style->getCheckedMarker() - : $style->getUncheckedMarker(); - } elseif ($item instanceof RadioItem) { - $markerType = $item->getChecked() - ? $style->getRadioMarker() - : $style->getUnradioMarker(); + if ($item instanceof CheckboxItem || $item instanceof RadioItem) { + $markerType = $item->getStyle()->getMarker($item->getChecked()); + $displaysExtra = $item->getStyle()->getDisplaysExtra(); + $itemExtraVal = $item->getStyle()->getItemExtra(); } else { - $markerType = $style->getMarker($isSelected); + $markerType = $style->getMarker($isSelected); + $displaysExtra = $style->getDisplaysExtra(); + $itemExtraVal = $style->getItemExtra(); } $marker = $item->canSelect() @@ -147,10 +145,10 @@ public function getRows(MenuStyle $style, bool $selected = false) : array : ''; $itemExtra = ''; - if ($style->getDisplaysExtra()) { + if ($displaysExtra) { $itemExtra = $item->showsItemExtra() - ? sprintf(' %s', $style->getItemExtra()) - : sprintf(' %s', str_repeat(' ', mb_strlen($style->getItemExtra()))); + ? sprintf(' %s', $itemExtraVal) + : sprintf(' %s', str_repeat(' ', mb_strlen($itemExtraVal))); } return $this->buildCell( diff --git a/src/MenuItem/ToggableTrait.php b/src/MenuItem/ToggableTrait.php deleted file mode 100644 index a56f77d0..00000000 --- a/src/MenuItem/ToggableTrait.php +++ /dev/null @@ -1,88 +0,0 @@ - $this instanceof CheckboxItem - ? $style->getCheckedMarker() - : $style->getRadioMarker(), - false => $this instanceof CheckboxItem - ? $style->getUncheckedMarker() - : $style->getUnradioMarker(), - ]; - - $marker = sprintf("%s", $markerTypes[$this->checked]); - - $length = $style->getDisplaysExtra() - ? $style->getContentWidth() - (mb_strlen($style->getItemExtra()) + 2) - : $style->getContentWidth(); - - $rows = explode( - "\n", - StringUtil::wordwrap( - sprintf('%s%s', $marker, $this->text), - $length, - sprintf("\n%s", str_repeat(' ', mb_strlen($marker))) - ) - ); - - return array_map(function ($row, $key) use ($style, $length) { - $text = $this->disabled ? $style->getDisabledItemText($row) : $row; - - if ($key === 0) { - return $this->showItemExtra - ? sprintf('%s%s %s', $text, str_repeat(' ', $length - mb_strlen($row)), $style->getItemExtra()) - : $text; - } - - return $text; - }, $rows, array_keys($rows)); - } - - /** - * Toggles checked state - */ - public function toggle() : void - { - $this->checked = !$this->checked; - } - - /** - * Sets checked state to true - */ - public function setChecked() : void - { - $this->checked = true; - } - - /** - * Sets checked state to false - */ - public function setUnchecked() : void - { - $this->checked = false; - } - - /** - * Whether or not the item is checked - */ - public function getChecked() : bool - { - return $this->checked; - } -} diff --git a/src/MenuStyle.php b/src/MenuStyle.php index f2139bca..47329f9d 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -69,26 +69,6 @@ class MenuStyle */ private $unselectedMarker; - /** - * @var string - */ - private $checkedMarker; - - /** - * @var string - */ - private $uncheckedMarker; - - /** - * @var string - */ - private $radioMarker; - - /** - * @var string - */ - private $unradioMarker; - /** * @var string */ @@ -178,10 +158,6 @@ class MenuStyle 'margin' => 2, 'selectedMarker' => '● ', 'unselectedMarker' => '○ ', - 'checkedMarker' => '[✔] ', - 'uncheckedMarker' => '[ ] ', - 'radioMarker' => '[●] ', - 'unradioMarker' => '[○] ', 'itemExtra' => '✔', 'displaysExtra' => false, 'titleSeparator' => '=', @@ -253,10 +229,6 @@ public function __construct(Terminal $terminal = null) $this->setMargin(self::$defaultStyleValues['margin']); $this->setSelectedMarker(self::$defaultStyleValues['selectedMarker']); $this->setUnselectedMarker(self::$defaultStyleValues['unselectedMarker']); - $this->setCheckedMarker(self::$defaultStyleValues['checkedMarker']); - $this->setUncheckedMarker(self::$defaultStyleValues['uncheckedMarker']); - $this->setRadioMarker(self::$defaultStyleValues['radioMarker']); - $this->setUnradioMarker(self::$defaultStyleValues['unradioMarker']); $this->setItemExtra(self::$defaultStyleValues['itemExtra']); $this->setDisplaysExtra(self::$defaultStyleValues['displaysExtra']); $this->setTitleSeparator(self::$defaultStyleValues['titleSeparator']); @@ -278,10 +250,6 @@ public function hasChangedFromDefaults() : bool $this->margin, $this->selectedMarker, $this->unselectedMarker, - $this->checkedMarker, - $this->uncheckedMarker, - $this->radioMarker, - $this->unradioMarker, $this->itemExtra, $this->displaysExtra, $this->titleSeparator, @@ -589,54 +557,6 @@ public function getMarker(bool $selected) : string return $selected ? $this->selectedMarker : $this->unselectedMarker; } - public function getCheckedMarker() : string - { - return $this->checkedMarker; - } - - public function setCheckedMarker(string $marker) : self - { - $this->checkedMarker = $marker; - - return $this; - } - - public function getUncheckedMarker() : string - { - return $this->uncheckedMarker; - } - - public function setUncheckedMarker(string $marker) : self - { - $this->uncheckedMarker = $marker; - - return $this; - } - - public function getRadioMarker() : string - { - return $this->radioMarker; - } - - public function setRadioMarker(string $marker) : self - { - $this->radioMarker = $marker; - - return $this; - } - - public function getUnradioMarker() : string - { - return $this->unradioMarker; - } - - public function setUnradioMarker(string $marker) : self - { - $this->unradioMarker = $marker; - - return $this; - } - public function setItemExtra(string $itemExtra) : self { $this->itemExtra = $itemExtra; diff --git a/src/Style/CheckboxStyle.php b/src/Style/CheckboxStyle.php new file mode 100644 index 00000000..1d661bac --- /dev/null +++ b/src/Style/CheckboxStyle.php @@ -0,0 +1,100 @@ + '[✔] ', + 'markerOff' => '[ ] ', + 'itemExtra' => '✔', + 'displaysExtra' => false, + ]; + + protected $markerOn = ''; + + protected $markerOff = ''; + + protected $itemExtra = ''; + + protected $displaysExtra = false; + + protected $custom = false; + + public function __construct() + { + $this->markerOn = self::DEFAULT_STYLES['markerOn']; + $this->markerOff = self::DEFAULT_STYLES['markerOff']; + $this->itemExtra = self::DEFAULT_STYLES['itemExtra']; + $this->displaysExtra = self::DEFAULT_STYLES['displaysExtra']; + } + + public function hasChangedFromDefaults() : bool + { + return $this->custom; + } + + public function getMarker(bool $selected) : string + { + return $selected ? $this->markerOn : $this->markerOff; + } + + public function getMarkerOn() : string + { + return $this->markerOn; + } + + public function setMarkerOn(string $marker) : self + { + $this->custom = true; + + $this->markerOn = $marker; + + return $this; + } + + public function getMarkerOff() : string + { + return $this->markerOff; + } + + public function setMarkerOff(string $marker) : self + { + $this->custom = true; + + $this->markerOff = $marker; + + return $this; + } + + public function getItemExtra() : string + { + return $this->itemExtra; + } + + public function setItemExtra(string $itemExtra) : self + { + $this->custom = true; + + $this->itemExtra = $itemExtra; + + // if we customise item extra, it means we most likely want to display it + $this->setDisplaysExtra(true); + + return $this; + } + + public function getDisplaysExtra() : bool + { + return $this->displaysExtra; + } + + public function setDisplaysExtra(bool $displaysExtra) : self + { + $this->custom = true; + + $this->displaysExtra = $displaysExtra; + + return $this; + } +} diff --git a/src/Style/RadioStyle.php b/src/Style/RadioStyle.php new file mode 100644 index 00000000..2f4b08fb --- /dev/null +++ b/src/Style/RadioStyle.php @@ -0,0 +1,100 @@ + '[●] ', + 'markerOff' => '[○] ', + 'itemExtra' => '✔', + 'displaysExtra' => false, + ]; + + protected $markerOn = ''; + + protected $markerOff = ''; + + protected $itemExtra = ''; + + protected $displaysExtra = false; + + protected $custom = false; + + public function __construct() + { + $this->markerOn = self::DEFAULT_STYLES['markerOn']; + $this->markerOff = self::DEFAULT_STYLES['markerOff']; + $this->itemExtra = self::DEFAULT_STYLES['itemExtra']; + $this->displaysExtra = self::DEFAULT_STYLES['displaysExtra']; + } + + public function hasChangedFromDefaults() : bool + { + return $this->custom; + } + + public function getMarker(bool $selected) : string + { + return $selected ? $this->markerOn : $this->markerOff; + } + + public function getMarkerOn() : string + { + return $this->markerOn; + } + + public function setMarkerOn(string $marker) : self + { + $this->custom = true; + + $this->markerOn = $marker; + + return $this; + } + + public function getMarkerOff() : string + { + return $this->markerOff; + } + + public function setMarkerOff(string $marker) : self + { + $this->custom = true; + + $this->markerOff = $marker; + + return $this; + } + + public function getItemExtra() : string + { + return $this->itemExtra; + } + + public function setItemExtra(string $itemExtra) : self + { + $this->custom = true; + + $this->itemExtra = $itemExtra; + + // if we customise item extra, it means we most likely want to display it + $this->setDisplaysExtra(true); + + return $this; + } + + public function getDisplaysExtra() : bool + { + return $this->displaysExtra; + } + + public function setDisplaysExtra(bool $displaysExtra) : self + { + $this->custom = true; + + $this->displaysExtra = $displaysExtra; + + return $this; + } +} diff --git a/test/Builder/CliMenuBuilderTest.php b/test/Builder/CliMenuBuilderTest.php index 244d5a33..d62221ba 100644 --- a/test/Builder/CliMenuBuilderTest.php +++ b/test/Builder/CliMenuBuilderTest.php @@ -68,8 +68,6 @@ public function testModifyStyles() : void $builder->setMargin(4); $builder->setUnselectedMarker('>'); $builder->setSelectedMarker('x'); - $builder->setUncheckedMarker('-'); - $builder->setCheckedMarker('+'); $builder->setItemExtra('*'); $builder->setTitleSeparator('-'); @@ -84,8 +82,6 @@ public function testModifyStyles() : void self::assertEquals(4, $style->getMargin()); self::assertEquals('>', $style->getUnselectedMarker()); self::assertEquals('x', $style->getSelectedMarker()); - self::assertEquals('-', $style->getUncheckedMarker()); - self::assertEquals('+', $style->getCheckedMarker()); self::assertEquals('*', $style->getItemExtra()); self::assertEquals('-', $style->getTitleSeparator()); } diff --git a/test/MenuItem/CheckableItemTest.php b/test/MenuItem/CheckboxItemTest.php similarity index 96% rename from test/MenuItem/CheckableItemTest.php rename to test/MenuItem/CheckboxItemTest.php index 98649b0e..fd708239 100644 --- a/test/MenuItem/CheckableItemTest.php +++ b/test/MenuItem/CheckboxItemTest.php @@ -141,11 +141,12 @@ public function testGetRowsWithItemExtra() : void $menuStyle = new MenuStyle($terminal); $menuStyle->setPaddingLeftRight(0); $menuStyle->setWidth(20); - $menuStyle->setItemExtra('[EXTRA]'); - $menuStyle->setDisplaysExtra(true); $item = new CheckboxItem('Item', function () { }, true); + $item->getStyle() + ->setItemExtra('[EXTRA]') + ->setDisplaysExtra(true); $this->assertEquals(['[ ] Item [EXTRA]'], $item->getRows($menuStyle)); } @@ -157,11 +158,12 @@ public function testGetRowsWithMultipleLinesWithItemExtra() : void $menuStyle = new MenuStyle($terminal); $menuStyle->setPaddingLeftRight(0); $menuStyle->setWidth(20); - $menuStyle->setItemExtra('[EXTRA]'); - $menuStyle->setDisplaysExtra(true); $item = new CheckboxItem('LONG ITEM LINE', function () { }, true); + $item->getStyle() + ->setItemExtra('[EXTRA]') + ->setDisplaysExtra(true); $this->assertEquals( [ "[ ] LONG [EXTRA]", diff --git a/test/MenuItem/RadioItemTest.php b/test/MenuItem/RadioItemTest.php index 00f667df..92475352 100644 --- a/test/MenuItem/RadioItemTest.php +++ b/test/MenuItem/RadioItemTest.php @@ -175,11 +175,12 @@ public function testGetRowsWithItemExtra() : void $menuStyle = new MenuStyle($terminal); $menuStyle->setPaddingLeftRight(0); $menuStyle->setWidth(20); - $menuStyle->setItemExtra('[EXTRA]'); - $menuStyle->setDisplaysExtra(true); $item = new RadioItem('Item', function () { }, true); + $item->getStyle() + ->setItemExtra('[EXTRA]') + ->setDisplaysExtra(true); $this->assertEquals(['[○] Item [EXTRA]'], $item->getRows($menuStyle)); } @@ -191,11 +192,12 @@ public function testGetRowsWithMultipleLinesWithItemExtra() : void $menuStyle = new MenuStyle($terminal); $menuStyle->setPaddingLeftRight(0); $menuStyle->setWidth(20); - $menuStyle->setItemExtra('[EXTRA]'); - $menuStyle->setDisplaysExtra(true); $item = new RadioItem('LONG ITEM LINE', function () { }, true); + $item->getStyle() + ->setItemExtra('[EXTRA]') + ->setDisplaysExtra(true); $this->assertEquals( [ "[○] LONG [EXTRA]", diff --git a/test/MenuItem/SplitItemTest.php b/test/MenuItem/SplitItemTest.php index bd85791b..0c138506 100644 --- a/test/MenuItem/SplitItemTest.php +++ b/test/MenuItem/SplitItemTest.php @@ -479,21 +479,17 @@ public function testCheckboxItem() : void ->method('getContentWidth') ->will($this->returnValue(30)); - $menuStyle - ->expects($this->any()) - ->method('getCheckedMarker') - ->willReturn('[✔] '); - - $menuStyle - ->expects($this->any()) - ->method('getUncheckedMarker') - ->willReturn('[ ] '); - $checkboxItem1 = new CheckboxItem('Item One', function () { }); + $checkboxItem1->getStyle() + ->setMarkerOff('[ ] ') + ->setMarkerOn('[✔] '); $checkboxItem2 = new CheckboxItem('Item Two', function () { }); + $checkboxItem2->getStyle() + ->setMarkerOff('[ ] ') + ->setMarkerOn('[✔] '); $item = new SplitItem( [ @@ -520,26 +516,22 @@ public function testRadioItem() : void ->method('getContentWidth') ->will($this->returnValue(30)); - $menuStyle - ->expects($this->any()) - ->method('getRadioMarker') - ->willReturn('[●] '); - - $menuStyle - ->expects($this->any()) - ->method('getUnradioMarker') - ->willReturn('[○] '); - - $checkboxItem1 = new RadioItem('Item One', function () { + $radioItem1 = new RadioItem('Item One', function () { }); + $radioItem1->getStyle() + ->setMarkerOn('[+] ') + ->setMarkerOff('[-] '); - $checkboxItem2 = new RadioItem('Item Two', function () { + $radioItem2 = new RadioItem('Item Two', function () { }); + $radioItem2->getStyle() + ->setMarkerOn('[+] ') + ->setMarkerOff('[-] '); $item = new SplitItem( [ - $checkboxItem1, - $checkboxItem2, + $radioItem1, + $radioItem2, ] ); @@ -561,14 +553,14 @@ public function testRadioItem() : void $item->setSelectedItemIndex(0); - self::assertEquals(['[○] Item One [○] Item Two '], $item->getRows($menuStyle, true)); + self::assertEquals(['[-] Item One [-] Item Two '], $item->getRows($menuStyle, true)); - $checkboxItem1->getSelectAction()($cliMenu); + $radioItem1->getSelectAction()($cliMenu); - self::assertEquals(['[●] Item One [○] Item Two '], $item->getRows($menuStyle, true)); + self::assertEquals(['[+] Item One [-] Item Two '], $item->getRows($menuStyle, true)); - $checkboxItem2->getSelectAction()($cliMenu); + $radioItem2->getSelectAction()($cliMenu); - self::assertEquals(['[○] Item One [●] Item Two '], $item->getRows($menuStyle, true)); + self::assertEquals(['[-] Item One [+] Item Two '], $item->getRows($menuStyle, true)); } } diff --git a/test/MenuStyleTest.php b/test/MenuStyleTest.php index 6294f351..1c954cc3 100644 --- a/test/MenuStyleTest.php +++ b/test/MenuStyleTest.php @@ -100,10 +100,6 @@ public function testGetterAndSetters() : void $style->setFg('yellow'); $style->setUnselectedMarker('-'); $style->setSelectedMarker('>'); - $style->setUncheckedMarker('/'); - $style->setCheckedMarker('+'); - $style->setUnradioMarker('O'); - $style->setRadioMarker('X'); $style->setItemExtra('EXTRA!'); $style->setDisplaysExtra(true); $style->setTitleSeparator('+'); @@ -121,10 +117,6 @@ public function testGetterAndSetters() : void self::assertSame('yellow', $style->getFg()); self::assertSame('-', $style->getUnselectedMarker()); self::assertSame('>', $style->getSelectedMarker()); - self::assertEquals('/', $style->getUncheckedMarker()); - self::assertEquals('+', $style->getCheckedMarker()); - self::assertEquals('O', $style->getUnradioMarker()); - self::assertEquals('X', $style->getRadioMarker()); self::assertSame('EXTRA!', $style->getItemExtra()); self::assertTrue($style->getDisplaysExtra()); self::assertSame('+', $style->getTitleSeparator());