Skip to content

Commit

Permalink
Merge pull request #100 from Lynesth/patch-14
Browse files Browse the repository at this point in the history
Add border styling
  • Loading branch information
AydinHassan authored May 7, 2018
2 parents 761de53 + cfa7953 commit d7bebfd
Show file tree
Hide file tree
Showing 6 changed files with 458 additions and 10 deletions.
1 change: 1 addition & 0 deletions examples/custom-styles.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
->setForegroundColour('black')
->setPadding(4)
->setMargin(4)
->setBorder(1, 2, 'red')
->setUnselectedMarker(' ')
->setSelectedMarker('>')
->setTitleSeparator('- ')
Expand Down
23 changes: 21 additions & 2 deletions src/CliMenu.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ protected function draw() : void

$frame->newLine(2);

if ($this->style->getBorderTopWidth() > 0) {
$frame->addRows($this->style->getBorderTopRows());
}

if ($this->title) {
$frame->addRows($this->drawMenuItem(new LineBreakItem()));
$frame->addRows($this->drawMenuItem(new StaticItem($this->title)));
Expand All @@ -331,6 +335,10 @@ protected function draw() : void
}, $this->items, array_keys($this->items));

$frame->addRows($this->drawMenuItem(new LineBreakItem()));

if ($this->style->getBorderBottomWidth() > 0) {
$frame->addRows($this->style->getBorderBottomRows());
}

$frame->newLine(2);

Expand Down Expand Up @@ -359,15 +367,26 @@ protected function drawMenuItem(MenuItemInterface $item, bool $selected = false)
? $this->style->getInvertedColoursSetCode()
: '';

return array_map(function ($row) use ($setColour, $invertedColour, $resetColour) {
if ($this->style->getBorderLeftWidth() || $this->style->getBorderRightWidth()) {
$borderColour = $this->style->getBorderColourCode();
} else {
$borderColour = '';
}

return array_map(function ($row) use ($setColour, $invertedColour, $resetColour, $borderColour) {
return sprintf(
"%s%s%s%s%s%s%s%s\n",
"%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
str_repeat(' ', $this->style->getMargin()),
$borderColour,
str_repeat(' ', $this->style->getBorderLeftWidth()),
$setColour,
$invertedColour,
str_repeat(' ', $this->style->getPadding()),
$row,
str_repeat(' ', $this->style->getRightHandPadding(mb_strlen(s::stripAnsiEscapeSequence($row)))),
$this->style->getInvertedColoursUnsetCode(),
$borderColour,
str_repeat(' ', $this->style->getBorderRightWidth()),
$resetColour,
str_repeat(' ', $this->style->getMargin())
);
Expand Down
40 changes: 39 additions & 1 deletion src/CliMenuBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,39 @@ public function setTitleSeparator(string $separator) : self
return $this;
}

public function setBorder(
int $topWidth,
$rightWidth = null,
$bottomWidth = null,
$leftWidth = null,
string $colour = null
) : self {
if (!is_int($rightWidth)) {
$colour = $rightWidth;
$rightWidth = $bottomWidth = $leftWidth = $topWidth;
} elseif (!is_int($bottomWidth)) {
$colour = $bottomWidth;
$bottomWidth = $topWidth;
$leftWidth = $rightWidth;
} elseif (!is_int($leftWidth)) {
$colour = $leftWidth;
$leftWidth = $rightWidth;
}

$this->style['borderTopWidth'] = $topWidth;
$this->style['borderRightWidth'] = $rightWidth;
$this->style['borderBottomWidth'] = $bottomWidth;
$this->style['borderLeftWidth'] = $leftWidth;

if (is_string($colour)) {
$this->style['borderColour'] = $colour;
} elseif ($colour !== null) {
throw new \InvalidArgumentException('Invalid colour');
}

return $this;
}

public function setTerminal(Terminal $terminal) : self
{
$this->terminal = $terminal;
Expand Down Expand Up @@ -344,7 +377,12 @@ private function buildStyle() : MenuStyle
->setUnselectedMarker($this->style['unselectedMarker'])
->setItemExtra($this->style['itemExtra'])
->setDisplaysExtra($this->style['displaysExtra'])
->setTitleSeparator($this->style['titleSeparator']);
->setTitleSeparator($this->style['titleSeparator'])
->setBorderTopWidth($this->style['borderTopWidth'])
->setBorderRightWidth($this->style['borderRightWidth'])
->setBorderBottomWidth($this->style['borderBottomWidth'])
->setBorderLeftWidth($this->style['borderLeftWidth'])
->setBorderColour($this->style['borderColour']);

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

Expand Down
204 changes: 202 additions & 2 deletions src/MenuStyle.php
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,41 @@ class MenuStyle
*/
private $coloursResetCode = "\033[0m";

/**
* @var int
*/
private $borderTopWidth;

/**
* @var int
*/
private $borderRightWidth;

/**
* @var int
*/
private $borderBottomWidth;

/**
* @var int
*/
private $borderLeftWidth;

/**
* @var string
*/
private $borderColour = 'white';

/**
* @var array
*/
private $borderTopRows = [];

/**
* @var array
*/
private $borderBottomRows = [];

/**
* @var bool
*/
Expand All @@ -115,6 +150,11 @@ class MenuStyle
'itemExtra' => '',
'displaysExtra' => false,
'titleSeparator' => '=',
'borderTopWidth' => 0,
'borderRightWidth' => 0,
'borderBottomWidth' => 0,
'borderLeftWidth' => 0,
'borderColour' => 'white',
'marginAuto' => false,
];

Expand Down Expand Up @@ -185,6 +225,11 @@ public function __construct(Terminal $terminal = null)
$this->setItemExtra(static::$defaultStyleValues['itemExtra']);
$this->setDisplaysExtra(static::$defaultStyleValues['displaysExtra']);
$this->setTitleSeparator(static::$defaultStyleValues['titleSeparator']);
$this->setBorderTopWidth(static::$defaultStyleValues['borderTopWidth']);
$this->setBorderRightWidth(static::$defaultStyleValues['borderRightWidth']);
$this->setBorderBottomWidth(static::$defaultStyleValues['borderBottomWidth']);
$this->setBorderLeftWidth(static::$defaultStyleValues['borderLeftWidth']);
$this->setBorderColour(static::$defaultStyleValues['borderColour']);
}

public function getDisabledItemText(string $text) : string
Expand Down Expand Up @@ -254,7 +299,9 @@ public function getColoursResetCode() : string
*/
protected function calculateContentWidth() : void
{
$this->contentWidth = $this->width - ($this->padding * 2);
$this->contentWidth = $this->width
- ($this->padding * 2)
- ($this->borderRightWidth + $this->borderLeftWidth);
}

public function getFg()
Expand Down Expand Up @@ -306,7 +353,9 @@ public function setWidth(int $width) : self
if ($this->marginAuto) {
$this->setMarginAuto();
}

$this->calculateContentWidth();
$this->generateBorderRows();

return $this;
}
Expand Down Expand Up @@ -334,7 +383,9 @@ public function setMarginAuto() : self
{
$this->marginAuto = true;
$this->margin = floor(($this->terminal->getWidth() - $this->width) / 2);


$this->generateBorderRows();

return $this;
}

Expand All @@ -343,6 +394,8 @@ public function setMargin(int $margin) : self
$this->marginAuto = false;
$this->margin = $margin;

$this->generateBorderRows();

return $this;
}

Expand Down Expand Up @@ -426,4 +479,151 @@ public function setTitleSeparator(string $actionSeparator) : self

return $this;
}

private function generateBorderRows() : void
{
$borderRow = sprintf(
"%s%s%s%s%s\n",
str_repeat(' ', $this->margin),
$this->getBorderColourCode(),
str_repeat(' ', $this->width),
$this->coloursResetCode,
str_repeat(' ', $this->margin)
);

$this->borderTopRows = array_fill(0, $this->borderTopWidth, $borderRow);
$this->borderBottomRows = array_fill(0, $this->borderBottomWidth, $borderRow);
}

public function getBorderTopRows() : array
{
return $this->borderTopRows;
}

public function getBorderBottomRows() : array
{
return $this->borderBottomRows;
}

/**
* Shorthand function to set all borders values at once
*/
public function setBorder(
int $topWidth,
$rightWidth = null,
$bottomWidth = null,
$leftWidth = null,
string $colour = null
) : self {
if (!is_int($rightWidth)) {
$colour = $rightWidth;
$rightWidth = $bottomWidth = $leftWidth = $topWidth;
} elseif (!is_int($bottomWidth)) {
$colour = $bottomWidth;
$bottomWidth = $topWidth;
$leftWidth = $rightWidth;
} elseif (!is_int($leftWidth)) {
$colour = $leftWidth;
$leftWidth = $rightWidth;
}

$this->borderTopWidth = $topWidth;
$this->borderRightWidth = $rightWidth;
$this->borderBottomWidth = $bottomWidth;
$this->borderLeftWidth = $leftWidth;

if (is_string($colour)) {
$this->setBorderColour($colour);
} elseif ($colour !== null) {
throw new \InvalidArgumentException('Invalid colour');
}

$this->calculateContentWidth();
$this->generateBorderRows();

return $this;
}

public function setBorderTopWidth(int $width) : self
{
$this->borderTopWidth = $width;

$this->generateBorderRows();

return $this;
}

public function setBorderRightWidth(int $width) : self
{
$this->borderRightWidth = $width;
$this->calculateContentWidth();

return $this;
}

public function setBorderBottomWidth(int $width) : self
{
$this->borderBottomWidth = $width;

$this->generateBorderRows();

return $this;
}

public function setBorderLeftWidth(int $width) : self
{
$this->borderLeftWidth = $width;
$this->calculateContentWidth();

return $this;
}

public function setBorderColour(string $colour, $fallback = null) : self
{
$this->borderColour = ColourUtil::validateColour(
$this->terminal,
$colour,
$fallback
);

$this->generateBorderRows();

return $this;
}

public function getBorderTopWidth() : int
{
return $this->borderTopWidth;
}

public function getBorderRightWidth() : int
{
return $this->borderRightWidth;
}

public function getBorderBottomWidth() : int
{
return $this->borderBottomWidth;
}

public function getBorderLeftWidth() : int
{
return $this->borderLeftWidth;
}

public function getBorderColour() : string
{
return $this->borderColour;
}

public function getBorderColourCode() : string
{
if (!ctype_digit($this->borderColour)) {
$borderColourCode = self::$availableBackgroundColors[$this->borderColour];
} else {
$borderColourCode = sprintf("48;5;%s", $this->borderColour);
}

return sprintf("\033[%sm", $borderColourCode);
}
}
Loading

0 comments on commit d7bebfd

Please sign in to comment.