Skip to content

Commit a5997fd

Browse files
authored
Merge branch 'master' into patch-17
2 parents dc3f0b5 + 06534f7 commit a5997fd

File tree

13 files changed

+313
-45
lines changed

13 files changed

+313
-45
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/CliMenu.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -442,55 +442,55 @@ public function getCurrentFrame() : Frame
442442
return $this->currentFrame;
443443
}
444444

445-
public function flash(string $text) : Flash
445+
public function flash(string $text, MenuStyle $style = null) : Flash
446446
{
447447
$this->guardSingleLine($text);
448448

449-
$style = (new MenuStyle($this->terminal))
449+
$style = $style ?? (new MenuStyle($this->terminal))
450450
->setBg('yellow')
451451
->setFg('red');
452452

453453
return new Flash($this, $style, $this->terminal, $text);
454454
}
455455

456-
public function confirm($text) : Confirm
456+
public function confirm(string $text, MenuStyle $style = null) : Confirm
457457
{
458458
$this->guardSingleLine($text);
459459

460-
$style = (new MenuStyle($this->terminal))
460+
$style = $style ?? (new MenuStyle($this->terminal))
461461
->setBg('yellow')
462462
->setFg('red');
463463

464464
return new Confirm($this, $style, $this->terminal, $text);
465465
}
466466

467-
public function askNumber() : Number
467+
public function askNumber(MenuStyle $style = null) : Number
468468
{
469469
$this->assertOpen();
470470

471-
$style = (new MenuStyle($this->terminal))
471+
$style = $style ?? (new MenuStyle($this->terminal))
472472
->setBg('yellow')
473473
->setFg('red');
474474

475475
return new Number(new InputIO($this, $this->terminal), $style);
476476
}
477477

478-
public function askText() : Text
478+
public function askText(MenuStyle $style = null) : Text
479479
{
480480
$this->assertOpen();
481481

482-
$style = (new MenuStyle($this->terminal))
482+
$style = $style ?? (new MenuStyle($this->terminal))
483483
->setBg('yellow')
484484
->setFg('red');
485485

486486
return new Text(new InputIO($this, $this->terminal), $style);
487487
}
488488

489-
public function askPassword() : Password
489+
public function askPassword(MenuStyle $style = null) : Password
490490
{
491491
$this->assertOpen();
492492

493-
$style = (new MenuStyle($this->terminal))
493+
$style = $style ?? (new MenuStyle($this->terminal))
494494
->setBg('yellow')
495495
->setFg('red');
496496

src/CliMenuBuilder.php

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

238+
public function setMarginAuto() : self
239+
{
240+
$this->style['marginAuto'] = true;
241+
242+
return $this;
243+
}
244+
238245
public function setMargin(int $margin) : self
239246
{
247+
Assertion::greaterOrEqualThan($margin, 0);
248+
249+
$this->style['marginAuto'] = false;
240250
$this->style['margin'] = $margin;
241251

242252
return $this;
@@ -325,17 +335,20 @@ private function getMenuStyle() : MenuStyle
325335

326336
private function buildStyle() : MenuStyle
327337
{
328-
return (new MenuStyle($this->terminal))
338+
$style = (new MenuStyle($this->terminal))
329339
->setFg($this->style['fg'])
330340
->setBg($this->style['bg'])
331341
->setWidth($this->style['width'])
332342
->setPadding($this->style['padding'])
333-
->setMargin($this->style['margin'])
334343
->setSelectedMarker($this->style['selectedMarker'])
335344
->setUnselectedMarker($this->style['unselectedMarker'])
336345
->setItemExtra($this->style['itemExtra'])
337346
->setDisplaysExtra($this->style['displaysExtra'])
338347
->setTitleSeparator($this->style['titleSeparator']);
348+
349+
$this->style['marginAuto'] ? $style->setMarginAuto() : $style->setMargin($this->style['margin']);
350+
351+
return $style;
339352
}
340353

341354
/**

src/Dialogue/Dialogue.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ protected function calculateCoordinates() : void
7474
//x
7575
$parentStyle = $this->parentMenu->getStyle();
7676
$dialogueHalfLength = (mb_strlen($this->text) + ($this->style->getPadding() * 2)) / 2;
77-
$widthHalfLength = ceil($parentStyle->getWidth() / 2);
77+
$widthHalfLength = ceil($parentStyle->getWidth() / 2 + $parentStyle->getMargin());
7878
$this->x = $widthHalfLength - $dialogueHalfLength;
7979
}
8080

src/Input/InputIO.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ private function calculateXPosition(Input $input, string $userInput) : int
132132

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

137137
return $parentHalfWidth - $halfWidth;
138138
}

src/MenuItem/AsciiArtItem.php

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ public function __construct(string $text, string $position = self::POSITION_CENT
4141
{
4242
Assertion::inArray($position, [self::POSITION_CENTER, self::POSITION_RIGHT, self::POSITION_LEFT]);
4343

44-
$this->text = $text;
44+
$this->text = implode("\n", array_map(function (string $line) {
45+
return rtrim($line, ' ');
46+
}, explode("\n", $text)));
4547
$this->position = $position;
4648
$this->alternateText = $alt;
4749
$this->artLength = max(array_map('mb_strlen', explode("\n", $text)));
@@ -57,27 +59,19 @@ public function getRows(MenuStyle $style, bool $selected = false) : array
5759
return $alternate->getRows($style, false);
5860
}
5961

60-
return array_map(function ($row) use ($style) {
61-
$length = mb_strlen($row);
62-
63-
$padding = $style->getContentWidth() - $length;
64-
62+
$padding = $style->getContentWidth() - $this->artLength;
63+
64+
return array_map(function ($row) use ($padding) {
6565
switch ($this->position) {
6666
case self::POSITION_LEFT:
67-
return $row;
6867
break;
6968
case self::POSITION_RIGHT:
70-
$row = rtrim($row);
71-
$padding = $padding - ($this->artLength - mb_strlen($row));
7269
$row = sprintf('%s%s', str_repeat(' ', $padding), $row);
7370
break;
7471
case self::POSITION_CENTER:
7572
default:
76-
$row = rtrim($row);
77-
$padding = $padding - ($this->artLength - mb_strlen($row));
78-
$left = ceil($padding/2);
79-
$right = $padding - $left;
80-
$row = sprintf('%s%s%s', str_repeat(' ', $left), $row, str_repeat(' ', $right));
73+
$left = ceil($padding / 2);
74+
$row = sprintf('%s%s', str_repeat(' ', $left), $row);
8175
break;
8276
}
8377

src/MenuStyle.php

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ class MenuStyle
9494
*/
9595
private $coloursResetCode = "\033[0m";
9696

97+
/**
98+
* @var bool
99+
*/
100+
private $marginAuto = false;
101+
97102
/**
98103
* Default Values
99104
*
@@ -110,6 +115,7 @@ class MenuStyle
110115
'itemExtra' => '',
111116
'displaysExtra' => false,
112117
'titleSeparator' => '=',
118+
'marginAuto' => false,
113119
];
114120

115121
public static function getDefaultStyleValues() : array
@@ -245,7 +251,7 @@ public function getColoursResetCode() : string
245251
*/
246252
protected function calculateContentWidth() : void
247253
{
248-
$this->contentWidth = $this->width - ($this->padding*2) - ($this->margin*2);
254+
$this->contentWidth = $this->width - ($this->padding * 2);
249255
}
250256

251257
public function getFg()
@@ -289,13 +295,14 @@ public function getWidth() : int
289295

290296
public function setWidth(int $width) : self
291297
{
292-
$availableWidth = $this->terminal->getWidth() - ($this->margin * 2) - ($this->padding * 2);
293-
294-
if ($width >= $availableWidth) {
295-
$width = $availableWidth;
298+
if ($width >= $this->terminal->getWidth()) {
299+
$width = $this->terminal->getWidth();
296300
}
297301

298302
$this->width = $width;
303+
if ($this->marginAuto) {
304+
$this->setMarginAuto();
305+
}
299306
$this->calculateContentWidth();
300307

301308
return $this;
@@ -320,12 +327,19 @@ public function getMargin() : int
320327
return $this->margin;
321328
}
322329

330+
public function setMarginAuto() : self
331+
{
332+
$this->marginAuto = true;
333+
$this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);
334+
335+
return $this;
336+
}
337+
323338
public function setMargin(int $margin) : self
324339
{
340+
$this->marginAuto = false;
325341
$this->margin = $margin;
326342

327-
$this->calculateContentWidth();
328-
329343
return $this;
330344
}
331345

test/CliMenuBuilderTest.php

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

503503
(new CliMenuBuilder)->disableMenu();
504504
}
505+
506+
/**
507+
* @dataProvider marginBelowZeroProvider
508+
*/
509+
public function testSetMarginThrowsExceptionIfValueIsNotZeroOrAbove(int $value) : void
510+
{
511+
self::expectException(\Assert\InvalidArgumentException::class);
512+
513+
514+
(new CliMenuBuilder)->setMargin($value);
515+
}
516+
517+
public function marginBelowZeroProvider() : array
518+
{
519+
return [[-1], [-2], [-10]];
520+
}
521+
522+
/**
523+
* @dataProvider marginAboveZeroProvider
524+
*/
525+
public function testSetMarginAcceptsZeroAndPositiveIntegers(int $value) : void
526+
{
527+
$menu = (new CliMenuBuilder)->setMargin($value)->build();
528+
529+
self::assertSame($value, $menu->getStyle()->getMargin());
530+
}
531+
532+
public function marginAboveZeroProvider() : array
533+
{
534+
return [[0], [1], [10], [50]];
535+
}
536+
537+
public function testSetMarginAutoAutomaticallyCalculatesMarginToCenter() : void
538+
{
539+
$terminal = self::createMock(Terminal::class);
540+
$terminal
541+
->expects($this->any())
542+
->method('getWidth')
543+
->will($this->returnValue(200));
544+
545+
$builder = new CliMenuBuilder;
546+
$menu = $builder
547+
->setTerminal($terminal)
548+
->setMarginAuto()
549+
->setWidth(100)
550+
->build();
551+
552+
self::assertSame(50, $menu->getStyle()->getMargin());
553+
}
554+
555+
public function testSetMarginAutoOverwritesSetMargin() : void
556+
{
557+
$terminal = self::createMock(Terminal::class);
558+
$terminal
559+
->expects($this->any())
560+
->method('getWidth')
561+
->will($this->returnValue(200));
562+
563+
$builder = new CliMenuBuilder;
564+
$menu = $builder
565+
->setTerminal($terminal)
566+
->setMargin(10)
567+
->setMarginAuto()
568+
->setWidth(100)
569+
->build();
570+
571+
self::assertSame(50, $menu->getStyle()->getMargin());
572+
}
573+
574+
public function testSetMarginManuallyOverwritesSetMarginAuto() : void
575+
{
576+
$terminal = self::createMock(Terminal::class);
577+
$terminal
578+
->expects($this->any())
579+
->method('getWidth')
580+
->will($this->returnValue(200));
581+
582+
$builder = new CliMenuBuilder;
583+
$menu = $builder
584+
->setTerminal($terminal)
585+
->setMarginAuto()
586+
->setMargin(10)
587+
->setWidth(100)
588+
->build();
589+
590+
self::assertSame(10, $menu->getStyle()->getMargin());
591+
}
505592

506593
private function checkItems(CliMenu $menu, array $expected) : void
507594
{

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')

0 commit comments

Comments
 (0)