Skip to content

margin out of contentWidth + add menu centering #103

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

Merged
merged 13 commits into from
May 7, 2018
25 changes: 25 additions & 0 deletions examples/basic-centered.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

use PhpSchool\CliMenu\CliMenu;
use PhpSchool\CliMenu\CliMenuBuilder;

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

$itemCallable = function (CliMenu $menu) {
echo $menu->getSelectedItem()->getText();
};

$menu = (new CliMenuBuilder)
->setTitle('Basic CLI Menu')
->addItem('First Item', $itemCallable)
->addItem('Make menu wider', function (CliMenu $menu) {
$menu->getStyle()->setWidth($menu->getStyle()->getWidth() + 10);
$menu->redraw();
})
->addItem('Third Item', $itemCallable)
->addLineBreak('-')
->setWidth(70)
->setMarginAuto()
->build();

$menu->open();
17 changes: 15 additions & 2 deletions src/CliMenuBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -230,8 +230,18 @@ public function setPadding(int $padding) : self
return $this;
}

public function setMarginAuto() : self
{
$this->style['marginAuto'] = true;

return $this;
}

public function setMargin(int $margin) : self
{
Assertion::greaterOrEqualThan($margin, 0);

$this->style['marginAuto'] = false;
$this->style['margin'] = $margin;

return $this;
Expand Down Expand Up @@ -320,17 +330,20 @@ private function getMenuStyle() : MenuStyle

private function buildStyle() : MenuStyle
{
return (new MenuStyle($this->terminal))
$style = (new MenuStyle($this->terminal))
->setFg($this->style['fg'])
->setBg($this->style['bg'])
->setWidth($this->style['width'])
->setPadding($this->style['padding'])
->setMargin($this->style['margin'])
->setSelectedMarker($this->style['selectedMarker'])
->setUnselectedMarker($this->style['unselectedMarker'])
->setItemExtra($this->style['itemExtra'])
->setDisplaysExtra($this->style['displaysExtra'])
->setTitleSeparator($this->style['titleSeparator']);

$this->style['marginAuto'] ? $style->setMarginAuto() : $style->setMargin($this->style['margin']);

return $style;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Dialogue/Dialogue.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected function calculateCoordinates() : void
//x
$parentStyle = $this->parentMenu->getStyle();
$dialogueHalfLength = (mb_strlen($this->text) + ($this->style->getPadding() * 2)) / 2;
$widthHalfLength = ceil($parentStyle->getWidth() / 2);
$widthHalfLength = ceil($parentStyle->getWidth() / 2 + $parentStyle->getMargin());
$this->x = $widthHalfLength - $dialogueHalfLength;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Input/InputIO.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private function calculateXPosition(Input $input, string $userInput) : int

$parentStyle = $this->parentMenu->getStyle();
$halfWidth = ($width + ($input->getStyle()->getPadding() * 2)) / 2;
$parentHalfWidth = ceil($parentStyle->getWidth() / 2);
$parentHalfWidth = ceil($parentStyle->getWidth() / 2 + $parentStyle->getMargin());

return $parentHalfWidth - $halfWidth;
}
Expand Down
28 changes: 21 additions & 7 deletions src/MenuStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@ class MenuStyle
*/
private $titleSeparator;

/**
* @var bool
*/
private $marginAuto = false;

/**
* Default Values
*
Expand All @@ -89,6 +94,7 @@ class MenuStyle
'itemExtra' => '',
'displaysExtra' => false,
'titleSeparator' => '=',
'marginAuto' => false,
];

public static function getDefaultStyleValues() : array
Expand Down Expand Up @@ -233,7 +239,7 @@ public function getUnselectedUnsetCode() : string
*/
protected function calculateContentWidth() : void
{
$this->contentWidth = $this->width - ($this->padding*2) - ($this->margin*2);
$this->contentWidth = $this->width - ($this->padding * 2);
}

public function getFg() : string
Expand Down Expand Up @@ -267,13 +273,14 @@ public function getWidth() : int

public function setWidth(int $width) : self
{
$availableWidth = $this->terminal->getWidth() - ($this->margin * 2) - ($this->padding * 2);

if ($width >= $availableWidth) {
$width = $availableWidth;
if ($width >= $this->terminal->getWidth()) {
$width = $this->terminal->getWidth();
}

$this->width = $width;
if ($this->marginAuto) {
$this->setMarginAuto();
}
$this->calculateContentWidth();

return $this;
Expand All @@ -298,12 +305,19 @@ public function getMargin() : int
return $this->margin;
}

public function setMarginAuto() : self
{
$this->marginAuto = true;
$this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);

return $this;
}

public function setMargin(int $margin) : self
{
$this->marginAuto = false;
$this->margin = $margin;

$this->calculateContentWidth();

return $this;
}

Expand Down
87 changes: 87 additions & 0 deletions test/CliMenuBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,93 @@ public function testThrowsExceptionWhenDisablingRootMenu() : void

(new CliMenuBuilder)->disableMenu();
}

/**
* @dataProvider marginBelowZeroProvider
*/
public function testSetMarginThrowsExceptionIfValueIsNotZeroOrAbove(int $value) : void
{
self::expectException(\Assert\InvalidArgumentException::class);


(new CliMenuBuilder)->setMargin($value);
}

public function marginBelowZeroProvider() : array
{
return [[-1], [-2], [-10]];
}

/**
* @dataProvider marginAboveZeroProvider
*/
public function testSetMarginAcceptsZeroAndPositiveIntegers(int $value) : void
{
$menu = (new CliMenuBuilder)->setMargin($value)->build();

self::assertSame($value, $menu->getStyle()->getMargin());
}

public function marginAboveZeroProvider() : array
{
return [[0], [1], [10], [50]];
}

public function testSetMarginAutoAutomaticallyCalculatesMarginToCenter() : void
{
$terminal = self::createMock(Terminal::class);
$terminal
->expects($this->any())
->method('getWidth')
->will($this->returnValue(200));

$builder = new CliMenuBuilder;
$menu = $builder
->setTerminal($terminal)
->setMarginAuto()
->setWidth(100)
->build();

self::assertSame(50, $menu->getStyle()->getMargin());
}

public function testSetMarginAutoOverwritesSetMargin() : void
{
$terminal = self::createMock(Terminal::class);
$terminal
->expects($this->any())
->method('getWidth')
->will($this->returnValue(200));

$builder = new CliMenuBuilder;
$menu = $builder
->setTerminal($terminal)
->setMargin(10)
->setMarginAuto()
->setWidth(100)
->build();

self::assertSame(50, $menu->getStyle()->getMargin());
}

public function testSetMarginManuallyOverwritesSetMarginAuto() : void
{
$terminal = self::createMock(Terminal::class);
$terminal
->expects($this->any())
->method('getWidth')
->will($this->returnValue(200));

$builder = new CliMenuBuilder;
$menu = $builder
->setTerminal($terminal)
->setMarginAuto()
->setMargin(10)
->setWidth(100)
->build();

self::assertSame(10, $menu->getStyle()->getMargin());
}

private function checkItems(CliMenu $menu, array $expected) : void
{
Expand Down
2 changes: 1 addition & 1 deletion test/CliMenuTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public function setUp()

$this->terminal->expects($this->any())
->method('getWidth')
->willReturn(50);
->willReturn(46);

$this->terminal->expects($this->any())
->method('write')
Expand Down
2 changes: 1 addition & 1 deletion test/Dialogue/ConfirmTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function setUp()

$this->terminal->expects($this->any())
->method('getWidth')
->willReturn(50);
->willReturn(46);

$this->terminal->expects($this->any())
->method('write')
Expand Down
2 changes: 1 addition & 1 deletion test/Dialogue/FlashTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function setUp()

$this->terminal->expects($this->any())
->method('getWidth')
->willReturn(50);
->willReturn(46);

$this->terminal->expects($this->any())
->method('write')
Expand Down
44 changes: 42 additions & 2 deletions test/MenuStyleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public function testWidthCalculation() : void
$style->setPadding(5);
$style->setMargin(5);

static::assertSame(280, $style->getContentWidth());
static::assertSame(290, $style->getContentWidth());
}

public function testRightHandPaddingCalculation() : void
Expand All @@ -171,6 +171,46 @@ public function testRightHandPaddingCalculation() : void
$style->setPadding(5);
$style->setMargin(5);

static::assertSame(235, $style->getRightHandPadding(50));
static::assertSame(245, $style->getRightHandPadding(50));
}

public function testMargin() : void
{
$style = $this->getMenuStyle();

$style->setWidth(300);
$style->setPadding(5);
$style->setMargin(5);

self::assertSame(5, $style->getMargin());
}

public function testMarginAutoCenters() : void
{
$style = $this->getMenuStyle();

$style->setWidth(300);
$style->setPadding(5);
$style->setMarginAuto();

self::assertSame(100, $style->getMargin());
self::assertSame(290, $style->getContentWidth());
}

public function testModifyWithWhenMarginAutoIsEnabledRecalculatesMargin() : void
{
$style = $this->getMenuStyle();

$style->setWidth(300);
$style->setPadding(5);
$style->setMarginAuto();

self::assertSame(100, $style->getMargin());
self::assertSame(290, $style->getContentWidth());

$style->setWidth(400);

self::assertSame(50, $style->getMargin());
self::assertSame(390, $style->getContentWidth());
}
}