Skip to content

Commit 5472d7d

Browse files
authored
Merge pull request #49 from php-school/dialouges
Dialogue feature
2 parents 0aa57bb + 8536871 commit 5472d7d

21 files changed

+1094
-14
lines changed

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,12 @@ Check out the [examples](examples) directory and run them to check out what is p
8888
##### Disabled Items & Submenus
8989
<img width="600" alt="submenu" src="https://cloud.githubusercontent.com/assets/2174476/19047849/868fa8c0-899b-11e6-9004-811c8da6d435.png">
9090

91+
##### Flash Dialogue
92+
<img width="600" alt="submenu" src="https://cloud.githubusercontent.com/assets/2817002/19786090/1f07dad6-9c94-11e6-91b0-c20ab2e6e27d.png">
93+
94+
##### Confirm Dialogue
95+
<img width="600" alt="submenu" src="https://cloud.githubusercontent.com/assets/2817002/19786092/215d2dc2-9c94-11e6-910d-191b7b74f4d2.png">
96+
9197
### API
9298

9399
The `CliMenu` object is constructed via the Builder class
@@ -412,6 +418,62 @@ $menu = (new CliMenuBuilder)
412418
$menu->open();
413419
```
414420

421+
#### Dialogues
422+
423+
##### Flash
424+
425+
Show a one line message over the top of the menu. It has a separate style object which is colored by default different
426+
to the menu. It can be modified to suit your own style. The dialogue is dismissed with any key press. In the example
427+
below we change the background color on the flash to green.
428+
429+
```php
430+
use PhpSchool\CliMenu\CliMenu;
431+
use PhpSchool\CliMenu\CliMenuBuilder;
432+
433+
$itemCallable = function (CliMenu $menu) {
434+
$flash = $menu->flash("PHP School FTW!!");
435+
$flash->getStyle()->setBg('green');
436+
$flash->display();
437+
};
438+
439+
$menu = (new CliMenuBuilder)
440+
->setTitle('Basic CLI Menu')
441+
->addItem('First Item', $itemCallable)
442+
->addItem('Second Item', $itemCallable)
443+
->addItem('Third Item', $itemCallable)
444+
->addLineBreak('-')
445+
->build();
446+
447+
$menu->open();
448+
```
449+
450+
##### Confirm
451+
452+
Prompts are very similar to flashes except that a button is shown which has to be selected to dismiss them. The button
453+
text can be customised.
454+
455+
```php
456+
use PhpSchool\CliMenu\CliMenu;
457+
use PhpSchool\CliMenu\CliMenuBuilder;
458+
459+
require_once(__DIR__ . '/../vendor/autoload.php');
460+
461+
$itemCallable = function (CliMenu $menu) {
462+
$menu->confirm('PHP School FTW!')
463+
->display('OK!');
464+
};
465+
466+
$menu = (new CliMenuBuilder)
467+
->setTitle('Basic CLI Menu')
468+
->addItem('First Item', $itemCallable)
469+
->addItem('Second Item', $itemCallable)
470+
->addItem('Third Item', $itemCallable)
471+
->addLineBreak('-')
472+
->build();
473+
474+
$menu->open();
475+
```
476+
415477
---
416478

417479
Once you get going you might just end up with something that looks a little like this...

examples/confirm.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
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+
$menu->confirm('PHP School FTW!')
10+
->display('OK');
11+
};
12+
13+
$menu = (new CliMenuBuilder)
14+
->setTitle('Basic CLI Menu')
15+
->addItem('First Item', $itemCallable)
16+
->addItem('Second Item', $itemCallable)
17+
->addItem('Third Item', $itemCallable)
18+
->addLineBreak('-')
19+
->build();
20+
21+
$menu->open();

examples/flash.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
$flash = $menu->flash("PHP School FTW!!");
10+
$flash->getStyle()->setBg('green');
11+
$flash->display();
12+
};
13+
14+
$menu = (new CliMenuBuilder)
15+
->setTitle('Basic CLI Menu')
16+
->addItem('First Item', $itemCallable)
17+
->addItem('Second Item', $itemCallable)
18+
->addItem('Third Item', $itemCallable)
19+
->addLineBreak('-')
20+
->build();
21+
22+
$menu->open();

src/CliMenu.php

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
use PhpSchool\CliMenu\MenuItem\LineBreakItem;
99
use PhpSchool\CliMenu\MenuItem\MenuItemInterface;
1010
use PhpSchool\CliMenu\MenuItem\StaticItem;
11+
use PhpSchool\CliMenu\Dialogue\Confirm;
12+
use PhpSchool\CliMenu\Dialogue\Flash;
1113
use PhpSchool\CliMenu\Terminal\TerminalFactory;
1214
use PhpSchool\CliMenu\Terminal\TerminalInterface;
1315
use PhpSchool\CliMenu\Util\StringUtil as s;
@@ -55,6 +57,11 @@ class CliMenu
5557
*/
5658
protected $parent;
5759

60+
/**
61+
* @var Frame|null
62+
*/
63+
private $currentFrame;
64+
5865
/**
5966
* @param string $title
6067
* @param array $items
@@ -258,28 +265,37 @@ protected function draw()
258265
$this->terminal->clean();
259266
$this->terminal->moveCursorToTop();
260267

261-
echo "\n\n";
268+
$frame = new Frame;
269+
270+
$frame->newLine(2);
262271

263272
if (is_string($this->title)) {
264-
$this->drawMenuItem(new LineBreakItem());
265-
$this->drawMenuItem(new StaticItem($this->title));
266-
$this->drawMenuItem(new LineBreakItem($this->style->getTitleSeparator()));
273+
$frame->addRows($this->drawMenuItem(new LineBreakItem()));
274+
$frame->addRows($this->drawMenuItem(new StaticItem($this->title)));
275+
$frame->addRows($this->drawMenuItem(new LineBreakItem($this->style->getTitleSeparator())));
267276
}
268277

269-
array_map(function ($item, $index) {
270-
$this->drawMenuItem($item, $index === $this->selectedItem);
278+
array_map(function ($item, $index) use ($frame) {
279+
$frame->addRows($this->drawMenuItem($item, $index === $this->selectedItem));
271280
}, $this->items, array_keys($this->items));
272281

273-
$this->drawMenuItem(new LineBreakItem());
282+
$frame->addRows($this->drawMenuItem(new LineBreakItem()));
283+
284+
$frame->newLine(2);
285+
286+
foreach ($frame->getRows() as $row) {
287+
echo $row;
288+
}
274289

275-
echo "\n\n";
290+
$this->currentFrame = $frame;
276291
}
277292

278293
/**
279294
* Draw a menu item
280295
*
281296
* @param MenuItemInterface $item
282297
* @param bool|false $selected
298+
* @return array
283299
*/
284300
protected function drawMenuItem(MenuItemInterface $item, $selected = false)
285301
{
@@ -293,9 +309,9 @@ protected function drawMenuItem(MenuItemInterface $item, $selected = false)
293309
? $this->style->getSelectedUnsetCode()
294310
: $this->style->getUnselectedUnsetCode();
295311

296-
foreach ($rows as $row) {
297-
echo sprintf(
298-
"%s%s%s%s%s%s%s",
312+
return array_map(function ($row) use ($setColour, $unsetColour) {
313+
return sprintf(
314+
"%s%s%s%s%s%s%s\n\r",
299315
str_repeat(' ', $this->style->getMargin()),
300316
$setColour,
301317
str_repeat(' ', $this->style->getPadding()),
@@ -304,9 +320,7 @@ protected function drawMenuItem(MenuItemInterface $item, $selected = false)
304320
$unsetColour,
305321
str_repeat(' ', $this->style->getMargin())
306322
);
307-
308-
echo "\n\r";
309-
}
323+
}, $rows);
310324
}
311325

312326
/**
@@ -379,4 +393,43 @@ public function getStyle()
379393
{
380394
return $this->style;
381395
}
396+
397+
public function getCurrentFrame()
398+
{
399+
return $this->currentFrame;
400+
}
401+
402+
/**
403+
* @param string $text
404+
* @return Flash
405+
*/
406+
public function flash($text)
407+
{
408+
if (strpos($text, "\n") !== false) {
409+
throw new \InvalidArgumentException;
410+
}
411+
412+
$style = (new MenuStyle($this->terminal))
413+
->setBg('yellow')
414+
->setFg('red');
415+
416+
return new Flash($this, $style, $this->terminal, $text);
417+
}
418+
419+
/**
420+
* @param string $text
421+
* @return Confirm
422+
*/
423+
public function confirm($text)
424+
{
425+
if (strpos($text, "\n") !== false) {
426+
throw new \InvalidArgumentException;
427+
}
428+
429+
$style = (new MenuStyle($this->terminal))
430+
->setBg('yellow')
431+
->setFg('red');
432+
433+
return new Confirm($this, $style, $this->terminal, $text);
434+
}
382435
}

src/Dialogue/Confirm.php

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace PhpSchool\CliMenu\Dialogue;
4+
5+
/**
6+
* @author Aydin Hassan <[email protected]>
7+
*/
8+
class Confirm extends Dialogue
9+
{
10+
11+
/**
12+
* Display confirmation with a button with the given text
13+
*
14+
* @param string $confirmText
15+
*/
16+
public function display($confirmText = 'OK')
17+
{
18+
$this->assertMenuOpen();
19+
20+
$this->terminal->moveCursorToRow($this->y);
21+
22+
$promptWidth = mb_strlen($this->text) + 4;
23+
24+
$this->emptyRow();
25+
26+
$this->write(sprintf(
27+
"%s%s%s%s%s\n",
28+
$this->style->getUnselectedSetCode(),
29+
str_repeat(' ', $this->style->getPadding()),
30+
$this->text,
31+
str_repeat(' ', $this->style->getPadding()),
32+
$this->style->getUnselectedUnsetCode()
33+
));
34+
35+
$this->emptyRow();
36+
37+
$confirmText = sprintf(' < %s > ', $confirmText);
38+
$leftFill = ($promptWidth / 2) - (mb_strlen($confirmText) / 2);
39+
40+
$this->write(sprintf(
41+
'%s%s%s',
42+
$this->style->getUnselectedSetCode(),
43+
str_repeat(' ', $leftFill),
44+
$this->style->getUnselectedSetCode()
45+
));
46+
47+
$this->write(
48+
sprintf(
49+
'%s%s%s',
50+
$this->style->getSelectedSetCode(),
51+
$confirmText,
52+
$this->style->getSelectedUnsetCode()
53+
),
54+
-1
55+
);
56+
57+
$this->write(
58+
sprintf(
59+
"%s%s%s\n",
60+
$this->style->getUnselectedSetCode(),
61+
str_repeat(' ', ceil($promptWidth - $leftFill - mb_strlen($confirmText))),
62+
$this->style->getSelectedUnsetCode()
63+
),
64+
-1
65+
);
66+
67+
$this->write(sprintf(
68+
"%s%s%s%s%s\n",
69+
$this->style->getUnselectedSetCode(),
70+
str_repeat(' ', $this->style->getPadding()),
71+
str_repeat(' ', mb_strlen($this->text)),
72+
str_repeat(' ', $this->style->getPadding()),
73+
$this->style->getUnselectedUnsetCode()
74+
));
75+
76+
$this->terminal->moveCursorToTop();
77+
$input = $this->terminal->getKeyedInput();
78+
79+
while ($input !== 'enter') {
80+
$input = $this->terminal->getKeyedInput();
81+
}
82+
83+
$this->parentMenu->redraw();
84+
}
85+
}

0 commit comments

Comments
 (0)