From e5547b4866c506a841db9086f5bf9227f1f30b03 Mon Sep 17 00:00:00 2001 From: Lynesth Date: Sat, 5 May 2018 19:16:48 +1100 Subject: [PATCH 01/11] margin out of contentWidth + add menu centering --- src/MenuStyle.php | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/MenuStyle.php b/src/MenuStyle.php index 9f630719..ebf3af87 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -233,7 +233,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 @@ -267,13 +267,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->margin === -1) { + $this->setMargin(-1); + } $this->calculateContentWidth(); return $this; @@ -300,9 +301,11 @@ public function getMargin() : int public function setMargin(int $margin) : self { - $this->margin = $margin; - - $this->calculateContentWidth(); + if ($this->margin === -1) { + $this->margin = floor(($this->terminal->getWidth() - $this->width) / 2); + } else { + $this->margin = $margin; + } return $this; } From 2eb39fec1cd5f56824d492c376e855d4178eee3b Mon Sep 17 00:00:00 2001 From: Lynesth Date: Sun, 6 May 2018 01:55:35 +1100 Subject: [PATCH 02/11] Fix centering of dialogues --- src/Dialogue/Dialogue.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Dialogue/Dialogue.php b/src/Dialogue/Dialogue.php index f9278222..aa0e343a 100644 --- a/src/Dialogue/Dialogue.php +++ b/src/Dialogue/Dialogue.php @@ -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; } From e32c64afc05d63d62965498d375a1a546daf2220 Mon Sep 17 00:00:00 2001 From: Lynesth Date: Sun, 6 May 2018 01:56:42 +1100 Subject: [PATCH 03/11] Fix centering of Inputs --- src/Input/InputIO.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Input/InputIO.php b/src/Input/InputIO.php index ae655cfd..d770c71d 100644 --- a/src/Input/InputIO.php +++ b/src/Input/InputIO.php @@ -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; } From 392646be119818203c8eb5402bce401f54137754 Mon Sep 17 00:00:00 2001 From: Lynesth Date: Mon, 7 May 2018 20:37:26 +1100 Subject: [PATCH 04/11] Fix wrong equality --- src/MenuStyle.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MenuStyle.php b/src/MenuStyle.php index ebf3af87..a50c3b0e 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -301,7 +301,7 @@ public function getMargin() : int public function setMargin(int $margin) : self { - if ($this->margin === -1) { + if ($margin === -1) { $this->margin = floor(($this->terminal->getWidth() - $this->width) / 2); } else { $this->margin = $margin; From 4d7940a4ce7b17b327d8468cdd19202091c943a8 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 11:50:37 +0200 Subject: [PATCH 05/11] Fix margin auto check --- src/MenuStyle.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MenuStyle.php b/src/MenuStyle.php index ebf3af87..3612f4ed 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -233,7 +233,7 @@ public function getUnselectedUnsetCode() : string */ protected function calculateContentWidth() : void { - $this->contentWidth = $this->width - ($this->padding*2); + $this->contentWidth = $this->width - ($this->padding * 2); } public function getFg() : string @@ -301,7 +301,7 @@ public function getMargin() : int public function setMargin(int $margin) : self { - if ($this->margin === -1) { + if ($margin === -1) { $this->margin = floor(($this->terminal->getWidth() - $this->width) / 2); } else { $this->margin = $margin; From 5503983280b30d2da067b3a4c3e48385c80c84f4 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 11:51:35 +0200 Subject: [PATCH 06/11] Add example for centering menu --- examples/basic-centered.php | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 examples/basic-centered.php diff --git a/examples/basic-centered.php b/examples/basic-centered.php new file mode 100644 index 00000000..6b6e758a --- /dev/null +++ b/examples/basic-centered.php @@ -0,0 +1,22 @@ +getSelectedItem()->getText(); +}; + +$menu = (new CliMenuBuilder) + ->setTitle('Basic CLI Menu') + ->addItem('First Item', $itemCallable) + ->addItem('Second Item', $itemCallable) + ->addItem('Third Item', $itemCallable) + ->addLineBreak('-') + ->setWidth(70) + ->setMargin(-1) + ->build(); + +$menu->open(); From f3d0dff7ff9bc92e4993511074a09a3b533057b4 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 11:53:11 +0200 Subject: [PATCH 07/11] Adjust tests for margins out of content width --- test/CliMenuTest.php | 2 +- test/Dialogue/ConfirmTest.php | 2 +- test/Dialogue/FlashTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/CliMenuTest.php b/test/CliMenuTest.php index eebc15e9..af288b9c 100644 --- a/test/CliMenuTest.php +++ b/test/CliMenuTest.php @@ -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') diff --git a/test/Dialogue/ConfirmTest.php b/test/Dialogue/ConfirmTest.php index 18ce0fd5..c98168d9 100644 --- a/test/Dialogue/ConfirmTest.php +++ b/test/Dialogue/ConfirmTest.php @@ -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') diff --git a/test/Dialogue/FlashTest.php b/test/Dialogue/FlashTest.php index 51b8c852..58ec514b 100644 --- a/test/Dialogue/FlashTest.php +++ b/test/Dialogue/FlashTest.php @@ -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') From 7161561c6aab2a0d42b5596aff98cb1d2085b5f3 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 11:55:14 +0200 Subject: [PATCH 08/11] Add tests for margin auto --- test/MenuStyleTest.php | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/test/MenuStyleTest.php b/test/MenuStyleTest.php index 37651c03..ad0c96f3 100644 --- a/test/MenuStyleTest.php +++ b/test/MenuStyleTest.php @@ -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 @@ -171,6 +171,29 @@ 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->setMargin(-1); + + self::assertSame(100, $style->getMargin()); + self::assertSame(290, $style->getContentWidth()); } } From fe3209eebd5faaef0e39822e4dda38b1ad5c0adb Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 13:02:37 +0200 Subject: [PATCH 09/11] Fix margin auto when updating width --- examples/basic-centered.php | 7 ++- src/CliMenuBuilder.php | 18 +++++++- src/MenuStyle.php | 25 ++++++++--- test/CliMenuBuilderTest.php | 87 +++++++++++++++++++++++++++++++++++++ test/MenuStyleTest.php | 19 +++++++- 5 files changed, 144 insertions(+), 12 deletions(-) diff --git a/examples/basic-centered.php b/examples/basic-centered.php index 6b6e758a..cdac52c7 100644 --- a/examples/basic-centered.php +++ b/examples/basic-centered.php @@ -12,11 +12,14 @@ $menu = (new CliMenuBuilder) ->setTitle('Basic CLI Menu') ->addItem('First Item', $itemCallable) - ->addItem('Second 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) - ->setMargin(-1) + ->setMarginAuto() ->build(); $menu->open(); diff --git a/src/CliMenuBuilder.php b/src/CliMenuBuilder.php index 3a2174b6..861589a7 100644 --- a/src/CliMenuBuilder.php +++ b/src/CliMenuBuilder.php @@ -230,8 +230,18 @@ public function setPadding(int $padding) : self return $this; } - public function setMargin(int $margin) : self + 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; @@ -320,7 +330,7 @@ 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']) @@ -331,6 +341,10 @@ private function buildStyle() : MenuStyle ->setItemExtra($this->style['itemExtra']) ->setDisplaysExtra($this->style['displaysExtra']) ->setTitleSeparator($this->style['titleSeparator']); + + $this->style['marginAuto'] ? $style->setMarginAuto() : $style->setMargin($this->style['margin']); + + return $style; } /** diff --git a/src/MenuStyle.php b/src/MenuStyle.php index 3612f4ed..c0a9493f 100644 --- a/src/MenuStyle.php +++ b/src/MenuStyle.php @@ -73,6 +73,11 @@ class MenuStyle */ private $titleSeparator; + /** + * @var bool + */ + private $marginAuto = false; + /** * Default Values * @@ -89,6 +94,7 @@ class MenuStyle 'itemExtra' => '✔', 'displaysExtra' => false, 'titleSeparator' => '=', + 'marginAuto' => false, ]; public static function getDefaultStyleValues() : array @@ -272,8 +278,8 @@ public function setWidth(int $width) : self } $this->width = $width; - if ($this->margin === -1) { - $this->setMargin(-1); + if ($this->marginAuto) { + $this->setMarginAuto(); } $this->calculateContentWidth(); @@ -299,13 +305,18 @@ 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 { - if ($margin === -1) { - $this->margin = floor(($this->terminal->getWidth() - $this->width) / 2); - } else { - $this->margin = $margin; - } + $this->marginAuto = false; + $this->margin = $margin; return $this; } diff --git a/test/CliMenuBuilderTest.php b/test/CliMenuBuilderTest.php index af096b2c..8cf6bc7d 100644 --- a/test/CliMenuBuilderTest.php +++ b/test/CliMenuBuilderTest.php @@ -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 { diff --git a/test/MenuStyleTest.php b/test/MenuStyleTest.php index ad0c96f3..407445b4 100644 --- a/test/MenuStyleTest.php +++ b/test/MenuStyleTest.php @@ -191,9 +191,26 @@ public function testMarginAutoCenters() : void $style->setWidth(300); $style->setPadding(5); - $style->setMargin(-1); + $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()); + } } From c8d0189fa622693a4b78b9fd9b05196a65be4aff Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 14:28:58 +0200 Subject: [PATCH 10/11] Remove redundant setMargin --- src/CliMenuBuilder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CliMenuBuilder.php b/src/CliMenuBuilder.php index 861589a7..60fbcbbb 100644 --- a/src/CliMenuBuilder.php +++ b/src/CliMenuBuilder.php @@ -335,7 +335,6 @@ private function buildStyle() : MenuStyle ->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']) From cfaa44d0f5397438ef418e55b028c115b6083be1 Mon Sep 17 00:00:00 2001 From: Aydin Hassan Date: Mon, 7 May 2018 14:29:23 +0200 Subject: [PATCH 11/11] CS --- src/CliMenuBuilder.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/CliMenuBuilder.php b/src/CliMenuBuilder.php index 60fbcbbb..8bcc742d 100644 --- a/src/CliMenuBuilder.php +++ b/src/CliMenuBuilder.php @@ -238,10 +238,10 @@ public function setMarginAuto() : self } public function setMargin(int $margin) : self - { + { Assertion::greaterOrEqualThan($margin, 0); - $this->style['marginAuto'] = false; + $this->style['marginAuto'] = false; $this->style['margin'] = $margin; return $this;