-
Notifications
You must be signed in to change notification settings - Fork 106
Checkbox + Radio item-level styling #205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report
@@ Coverage Diff @@
## master #205 +/- ##
============================================
- Coverage 93.91% 92.48% -1.44%
- Complexity 516 559 +43
============================================
Files 29 30 +1
Lines 1561 1689 +128
============================================
+ Hits 1466 1562 +96
- Misses 95 127 +32
Continue to review full report at Codecov.
|
|
||
public function __construct() | ||
{ | ||
$this->setMarkerOn(self::DEFAULT_STYLES['markerOn']); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this automatically set it as custom?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but then it has $this->custom = false;
src/Builder/SplitItemBuilder.php
Outdated
$menu->radioStyle(function (RadioStyle $style) { | ||
$style->fromArray($this->menu->getRadioStyle()->toArray()); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above
src/Builder/CliMenuBuilder.php
Outdated
|
||
public function radioStyle(callable $itemCallable) : self | ||
{ | ||
$this->menu->radioStyle($itemCallable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$itemCallable($this->menu->getRadioStyle())
src/Builder/SplitItemBuilder.php
Outdated
@@ -139,4 +168,18 @@ public function build() : SplitItem | |||
{ | |||
return $this->splitItem; | |||
} | |||
|
|||
public function checkboxStyle(callable $itemCallable) : self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand this - Isn't this modifying the parent menu checkbox style?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's for changing the style for items defined within an addSplitItem()
call:
$menu = (new CliMenuBuilder)
->setWidth(150)
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->addSubMenu('Sub Menu on a split item', function (CliMenuBuilder $b) {
$b->setTitle('Behold the awesomeness')
->addItem('This is awesome', function() { print 'Yes!'; })
->addSplitItem(function (SplitItemBuilder $b) {
$b
->checkboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOn('[x]');
})
->addItem('Split Item 1', function() { print 'Item 1!'; })
->addItem('Split Item 2', function() { print 'Item 2!'; })
->addItem('Split Item 3', function() { print 'Item 3!'; })
->addSubMenu('Split Item Nested Sub Menu', function (CliMenuBuilder $b) {
$b->addItem('One', function() { print 'One!'; })
->addItem('Two', function() { print 'Two!'; })
->addItem('Three', function() { print 'Three!'; });
});
});
})
->addItem('Item 2', $itemCallable)
->addStaticItem('Item 3 - Static')
->addItem('Item 4', $itemCallable);
})
->build();
CliMenuBuilder::addSplitItem()
's style objects are separate from SplitItemBuilder
's
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, it doesn't seem to work for me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<?php
use PhpSchool\CliMenu\Builder\SplitItemBuilder;
use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\CheckboxStyle;
require_once(__DIR__ . '/../vendor/autoload.php');
$itemCallable = function (CliMenu $menu) {
echo $menu->getSelectedItem()->getText();
};
$menu = (new CliMenuBuilder)
->setWidth(150)
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->addSubMenu('Sub Menu on a split item', function (CliMenuBuilder $b) {
$b->setTitle('Behold the awesomeness')
->addItem('This is awesome', function() { print 'Yes!'; })
->addSplitItem(function (SplitItemBuilder $b) {
$b
->modifyCheckboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOn('[x] ');
})
->addCheckboxItem('Rust', function() { print 'Item 1!'; })
->addCheckboxItem('C++', function() { print 'Item 1!'; })
->addCheckboxItem('Go', function() { print 'Item 1!'; })
->addItem('Split Item 1', function() { print 'Item 1!'; })
->addItem('Split Item 2', function() { print 'Item 2!'; })
->addItem('Split Item 3', function() { print 'Item 3!'; })
->addSubMenu('Split Item Nested Sub Menu', function (CliMenuBuilder $b) {
$b->addItem('One', function() { print 'One!'; })
->addItem('Two', function() { print 'Two!'; })
->addItem('Three', function() { print 'Three!'; });
});
});
})
->addItem('Item 2', $itemCallable)
->addStaticItem('Item 3 - Static')
->addItem('Item 4', $itemCallable);
})
->build();
$menu->open();
Checkbox + Radio item-level styling - CR Changes
Updates README radioStyle -> modifyRadioStyle
if (!$menu->getCheckboxStyle()->hasChangedFromDefaults()) { | ||
$menu->setCheckboxStyle(clone $this->menu->getCheckboxStyle()); | ||
} | ||
|
||
if (!$menu->getRadioStyle()->hasChangedFromDefaults()) { | ||
$menu->setRadioStyle(clone $this->menu->getRadioStyle()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could extract this to a private method, since we do it below as well. But we can do that later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Above even.
src/Builder/SplitItemBuilder.php
Outdated
public function __construct(CliMenu $menu) | ||
{ | ||
$this->menu = $menu; | ||
$this->splitItem = new SplitItem(); | ||
|
||
$this->checkboxStyle = new CheckboxStyle(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this seems to be inconsistent with the way CliMenu
and CliMenuBuilder
work. CliMenu
holds the style instances, not the builder. The builder proxies to them. But here the SplitItemBuilder
contains the style instances. Can we make it similar to the CliMenuBuilder
works?
return $this; | ||
} | ||
|
||
public function modifyCheckboxStyle(callable $itemCallable) : self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually think we should drop this. It's took me a while but I think I get what you are doing. If you change the styles in a splititem builder, they persist back to the parent menu. I think it makes the code very confusing. I would rather we just not allow to modify the styles in the SplitItem
. Or rather if you modify the styles, it only applies to the split item and not the parent menu.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style is always limited only to the current scope and any children:
<?php
use PhpSchool\CliMenu\Builder\SplitItemBuilder;
use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\CheckboxStyle;
require_once(__DIR__ . '/../vendor/autoload.php');
$itemCallable = function (CliMenu $menu) {
echo $menu->getSelectedItem()->getText();
};
$menu = (new CliMenuBuilder)
->setTitle('Select a Language')
->addCheckboxItem('Rust', $itemCallable)
->addCheckboxItem('C++', $itemCallable)
->addCheckboxItem('Go', $itemCallable)
->addCheckboxItem('Java', $itemCallable)
->addCheckboxItem('C', $itemCallable)
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->setGutter(5)
->modifyCheckboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOff('ooo')
->setMarkerOn('xxx');
})
->addCheckboxItem('Rust', $itemCallable)
->addCheckboxItem('C++', $itemCallable)
->addCheckboxItem('Go', $itemCallable)
->addCheckboxItem('Java', $itemCallable)
->addCheckboxItem('C', $itemCallable)
;
})
->build();
$menu->open();
The parent should never be affected from the modify*Style()
methods:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually you're right, there's a bug where changing in a child updates the parent:
<?php
use PhpSchool\CliMenu\Builder\SplitItemBuilder;
use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\Builder\CliMenuBuilder;
use PhpSchool\CliMenu\Style\CheckboxStyle;
require_once(__DIR__ . '/../vendor/autoload.php');
$itemCallable = function (CliMenu $menu) {
echo $menu->getSelectedItem()->getText();
};
$menu = (new CliMenuBuilder)
->setTitle('Select a Language')
->addCheckboxItem('1-A', $itemCallable)
->addCheckboxItem('1-B', $itemCallable)
->addSplitItem(function (SplitItemBuilder $b) use ($itemCallable) {
$b->setGutter(5)
->addCheckboxItem('2-A', $itemCallable)
->modifyCheckboxStyle(function (CheckboxStyle $style) {
$style->setMarkerOff('o ')
->setMarkerOn('x ');
})
->addCheckboxItem('2-B', $itemCallable)
->addSubMenu('Options', function (CliMenuBuilder $b) use ($itemCallable) {
$b->setTitle('CLI Menu > Options')
->addCheckboxItem('Rust', $itemCallable)
->addCheckboxItem('C++', $itemCallable)
->addCheckboxItem('Go', $itemCallable)
->addCheckboxItem('Java', $itemCallable)
->addCheckboxItem('C', $itemCallable)
->addLineBreak('-');
})
->addCheckboxItem('2-C', $itemCallable)
->addCheckboxItem('2-D', $itemCallable)
->addCheckboxItem('2-E', $itemCallable)
;
})
->addCheckboxItem('1-C', $itemCallable)
->addCheckboxItem('1-D', $itemCallable)
->addCheckboxItem('1-E', $itemCallable)
->build();
$menu->open();
I'll fix and add a test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Phew 😅 Thought I was going crazy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I see, because SplitMenuBuilder::$menu
is the exact same instance as CliMenuBuilder::$menu
.
This is why SplitMenuBuilder
had its own style instances (removed in #208).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, I think the problem is that I had a fundamental misunderstanding on the SplitItem.
I was thinking this was a separate menu ala submenu, but it's simply a horizontal partitioner of the current menu.
You're completely right, SplitItemBuilder shouldn't have any of the radio/checkbox style methods, and should not have its own style instance(s).
SplitItemBuilder should reference menu styles
Please review and merge #210 before this PR. It is going to be required for this process to work properly, and since there have been a ton of changes and I messed up on the SplitItem styling (#205 (comment)) it's probably best if I create a new PR without all the changes. |
@jtreminio #210 is merged now. Thank you. I think these changes should be a lot simpler now. |
Competing PR at #211 |
#204 without checkbox rename
Related to #203 and #200
CheckableItem
toCheckboxItem
This does not fix the nested-style issue from #201