From b4968db144ce8fa435c0fe17d980fabf8ac238d1 Mon Sep 17 00:00:00 2001 From: Lynesth Date: Wed, 2 May 2018 00:14:41 +1100 Subject: [PATCH] Adds custom control mapping Allow mapping custom keys to callables. --- src/CliMenu.php | 56 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 48 insertions(+), 8 deletions(-) diff --git a/src/CliMenu.php b/src/CliMenu.php index 99d2bcc3..51ee9d01 100644 --- a/src/CliMenu.php +++ b/src/CliMenu.php @@ -63,6 +63,25 @@ class CliMenu */ protected $parent; + /** + * @var array + */ + protected $defaultControlMappings = [ + '^P' => InputCharacter::UP, + 'k' => InputCharacter::UP, + '^K' => InputCharacter::DOWN, + 'j' => InputCharacter::DOWN, + "\r" => InputCharacter::ENTER, + ' ' => InputCharacter::ENTER, + 'l' => InputCharacter::LEFT, + 'm' => InputCharacter::RIGHT, + ]; + + /** + * @var array + */ + protected $customControlMappings = []; + /** * @var Frame */ @@ -156,6 +175,30 @@ private function selectFirstItem() : void } } + /** + * Adds a custom control mapping + */ + public function addCustomControlMapping(string $input, callable $callable) : void + { + if (isset($this->defaultControlMappings[$input]) || isset($this->customControlMappings[$input])) { + throw new \InvalidArgumentException('Cannot rebind this input.'); + } + + $this->customControlMappings[$input] = $callable; + } + + /** + * Removes a custom control mapping + */ + public function removeCustomControlMapping(string $input) : void + { + if (!isset($this->customControlMappings[$input])) { + throw new \InvalidArgumentException('This input is not registered.'); + } + + unset($this->customControlMappings[$input]); + } + /** * Display menu and capture input */ @@ -164,17 +207,14 @@ private function display() : void $this->draw(); $reader = new NonCanonicalReader($this->terminal); - $reader->addControlMappings([ - '^P' => InputCharacter::UP, - 'k' => InputCharacter::UP, - '^K' => InputCharacter::DOWN, - 'j' => InputCharacter::DOWN, - "\r" => InputCharacter::ENTER, - ' ' => InputCharacter::ENTER, - ]); + $reader->addControlMappings($this->defaultControlMappings); while ($this->isOpen() && $char = $reader->readCharacter()) { if (!$char->isHandledControl()) { + $rawChar = $char->get(); + if (isset($this->customControlMappings[$rawChar])) { + $this->customControlMappings[$rawChar]($this); + } continue; }