Skip to content

Commit 4b40002

Browse files
authored
Merge pull request #1 from php-school/margin-auto-fix
Margin auto fix
2 parents 392646b + cfaa44d commit 4b40002

File tree

8 files changed

+191
-15
lines changed

8 files changed

+191
-15
lines changed

examples/basic-centered.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
use PhpSchool\CliMenu\CliMenu;
4+
use PhpSchool\CliMenu\CliMenuBuilder;
5+
6+
require_once(__DIR__ . '/../vendor/autoload.php');
7+
8+
$itemCallable = function (CliMenu $menu) {
9+
echo $menu->getSelectedItem()->getText();
10+
};
11+
12+
$menu = (new CliMenuBuilder)
13+
->setTitle('Basic CLI Menu')
14+
->addItem('First Item', $itemCallable)
15+
->addItem('Make menu wider', function (CliMenu $menu) {
16+
$menu->getStyle()->setWidth($menu->getStyle()->getWidth() + 10);
17+
$menu->redraw();
18+
})
19+
->addItem('Third Item', $itemCallable)
20+
->addLineBreak('-')
21+
->setWidth(70)
22+
->setMarginAuto()
23+
->build();
24+
25+
$menu->open();

src/CliMenuBuilder.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,8 +230,18 @@ public function setPadding(int $padding) : self
230230
return $this;
231231
}
232232

233+
public function setMarginAuto() : self
234+
{
235+
$this->style['marginAuto'] = true;
236+
237+
return $this;
238+
}
239+
233240
public function setMargin(int $margin) : self
234241
{
242+
Assertion::greaterOrEqualThan($margin, 0);
243+
244+
$this->style['marginAuto'] = false;
235245
$this->style['margin'] = $margin;
236246

237247
return $this;
@@ -320,17 +330,20 @@ private function getMenuStyle() : MenuStyle
320330

321331
private function buildStyle() : MenuStyle
322332
{
323-
return (new MenuStyle($this->terminal))
333+
$style = (new MenuStyle($this->terminal))
324334
->setFg($this->style['fg'])
325335
->setBg($this->style['bg'])
326336
->setWidth($this->style['width'])
327337
->setPadding($this->style['padding'])
328-
->setMargin($this->style['margin'])
329338
->setSelectedMarker($this->style['selectedMarker'])
330339
->setUnselectedMarker($this->style['unselectedMarker'])
331340
->setItemExtra($this->style['itemExtra'])
332341
->setDisplaysExtra($this->style['displaysExtra'])
333342
->setTitleSeparator($this->style['titleSeparator']);
343+
344+
$this->style['marginAuto'] ? $style->setMarginAuto() : $style->setMargin($this->style['margin']);
345+
346+
return $style;
334347
}
335348

336349
/**

src/MenuStyle.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ class MenuStyle
7373
*/
7474
private $titleSeparator;
7575

76+
/**
77+
* @var bool
78+
*/
79+
private $marginAuto = false;
80+
7681
/**
7782
* Default Values
7883
*
@@ -89,6 +94,7 @@ class MenuStyle
8994
'itemExtra' => '',
9095
'displaysExtra' => false,
9196
'titleSeparator' => '=',
97+
'marginAuto' => false,
9298
];
9399

94100
public static function getDefaultStyleValues() : array
@@ -233,7 +239,7 @@ public function getUnselectedUnsetCode() : string
233239
*/
234240
protected function calculateContentWidth() : void
235241
{
236-
$this->contentWidth = $this->width - ($this->padding*2);
242+
$this->contentWidth = $this->width - ($this->padding * 2);
237243
}
238244

239245
public function getFg() : string
@@ -272,8 +278,8 @@ public function setWidth(int $width) : self
272278
}
273279

274280
$this->width = $width;
275-
if ($this->margin === -1) {
276-
$this->setMargin(-1);
281+
if ($this->marginAuto) {
282+
$this->setMarginAuto();
277283
}
278284
$this->calculateContentWidth();
279285

@@ -299,13 +305,18 @@ public function getMargin() : int
299305
return $this->margin;
300306
}
301307

308+
public function setMarginAuto() : self
309+
{
310+
$this->marginAuto = true;
311+
$this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);
312+
313+
return $this;
314+
}
315+
302316
public function setMargin(int $margin) : self
303317
{
304-
if ($margin === -1) {
305-
$this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);
306-
} else {
307-
$this->margin = $margin;
308-
}
318+
$this->marginAuto = false;
319+
$this->margin = $margin;
309320

310321
return $this;
311322
}

test/CliMenuBuilderTest.php

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,93 @@ public function testThrowsExceptionWhenDisablingRootMenu() : void
437437

438438
(new CliMenuBuilder)->disableMenu();
439439
}
440+
441+
/**
442+
* @dataProvider marginBelowZeroProvider
443+
*/
444+
public function testSetMarginThrowsExceptionIfValueIsNotZeroOrAbove(int $value) : void
445+
{
446+
self::expectException(\Assert\InvalidArgumentException::class);
447+
448+
449+
(new CliMenuBuilder)->setMargin($value);
450+
}
451+
452+
public function marginBelowZeroProvider() : array
453+
{
454+
return [[-1], [-2], [-10]];
455+
}
456+
457+
/**
458+
* @dataProvider marginAboveZeroProvider
459+
*/
460+
public function testSetMarginAcceptsZeroAndPositiveIntegers(int $value) : void
461+
{
462+
$menu = (new CliMenuBuilder)->setMargin($value)->build();
463+
464+
self::assertSame($value, $menu->getStyle()->getMargin());
465+
}
466+
467+
public function marginAboveZeroProvider() : array
468+
{
469+
return [[0], [1], [10], [50]];
470+
}
471+
472+
public function testSetMarginAutoAutomaticallyCalculatesMarginToCenter() : void
473+
{
474+
$terminal = self::createMock(Terminal::class);
475+
$terminal
476+
->expects($this->any())
477+
->method('getWidth')
478+
->will($this->returnValue(200));
479+
480+
$builder = new CliMenuBuilder;
481+
$menu = $builder
482+
->setTerminal($terminal)
483+
->setMarginAuto()
484+
->setWidth(100)
485+
->build();
486+
487+
self::assertSame(50, $menu->getStyle()->getMargin());
488+
}
489+
490+
public function testSetMarginAutoOverwritesSetMargin() : void
491+
{
492+
$terminal = self::createMock(Terminal::class);
493+
$terminal
494+
->expects($this->any())
495+
->method('getWidth')
496+
->will($this->returnValue(200));
497+
498+
$builder = new CliMenuBuilder;
499+
$menu = $builder
500+
->setTerminal($terminal)
501+
->setMargin(10)
502+
->setMarginAuto()
503+
->setWidth(100)
504+
->build();
505+
506+
self::assertSame(50, $menu->getStyle()->getMargin());
507+
}
508+
509+
public function testSetMarginManuallyOverwritesSetMarginAuto() : void
510+
{
511+
$terminal = self::createMock(Terminal::class);
512+
$terminal
513+
->expects($this->any())
514+
->method('getWidth')
515+
->will($this->returnValue(200));
516+
517+
$builder = new CliMenuBuilder;
518+
$menu = $builder
519+
->setTerminal($terminal)
520+
->setMarginAuto()
521+
->setMargin(10)
522+
->setWidth(100)
523+
->build();
524+
525+
self::assertSame(10, $menu->getStyle()->getMargin());
526+
}
440527

441528
private function checkItems(CliMenu $menu, array $expected) : void
442529
{

test/CliMenuTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public function setUp()
3838

3939
$this->terminal->expects($this->any())
4040
->method('getWidth')
41-
->willReturn(50);
41+
->willReturn(46);
4242

4343
$this->terminal->expects($this->any())
4444
->method('write')

test/Dialogue/ConfirmTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function setUp()
3535

3636
$this->terminal->expects($this->any())
3737
->method('getWidth')
38-
->willReturn(50);
38+
->willReturn(46);
3939

4040
$this->terminal->expects($this->any())
4141
->method('write')

test/Dialogue/FlashTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function setUp()
3535

3636
$this->terminal->expects($this->any())
3737
->method('getWidth')
38-
->willReturn(50);
38+
->willReturn(46);
3939

4040
$this->terminal->expects($this->any())
4141
->method('write')

test/MenuStyleTest.php

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ public function testWidthCalculation() : void
160160
$style->setPadding(5);
161161
$style->setMargin(5);
162162

163-
static::assertSame(280, $style->getContentWidth());
163+
static::assertSame(290, $style->getContentWidth());
164164
}
165165

166166
public function testRightHandPaddingCalculation() : void
@@ -171,6 +171,46 @@ public function testRightHandPaddingCalculation() : void
171171
$style->setPadding(5);
172172
$style->setMargin(5);
173173

174-
static::assertSame(235, $style->getRightHandPadding(50));
174+
static::assertSame(245, $style->getRightHandPadding(50));
175+
}
176+
177+
public function testMargin() : void
178+
{
179+
$style = $this->getMenuStyle();
180+
181+
$style->setWidth(300);
182+
$style->setPadding(5);
183+
$style->setMargin(5);
184+
185+
self::assertSame(5, $style->getMargin());
186+
}
187+
188+
public function testMarginAutoCenters() : void
189+
{
190+
$style = $this->getMenuStyle();
191+
192+
$style->setWidth(300);
193+
$style->setPadding(5);
194+
$style->setMarginAuto();
195+
196+
self::assertSame(100, $style->getMargin());
197+
self::assertSame(290, $style->getContentWidth());
198+
}
199+
200+
public function testModifyWithWhenMarginAutoIsEnabledRecalculatesMargin() : void
201+
{
202+
$style = $this->getMenuStyle();
203+
204+
$style->setWidth(300);
205+
$style->setPadding(5);
206+
$style->setMarginAuto();
207+
208+
self::assertSame(100, $style->getMargin());
209+
self::assertSame(290, $style->getContentWidth());
210+
211+
$style->setWidth(400);
212+
213+
self::assertSame(50, $style->getMargin());
214+
self::assertSame(390, $style->getContentWidth());
175215
}
176216
}

0 commit comments

Comments
 (0)