prompt = $prompt; $this->reader = $reader ?: new Stdin(); $this->checkboxes = $this->buildCheckboxes($options); } /** * Do it! Prompt the user for information! * * @return string */ public function prompt() { $this->output->write($this->parser->apply($this->promptFormatted())); $this->writeCheckboxes(); $this->util->system->exec('stty sane'); return $this->checkboxes->getCheckedValues(); } /** * Build out the checkboxes * * @param array $options * * @return Checkbox\CheckboxGroup */ protected function buildCheckboxes(array $options) { return new Checkbox\CheckboxGroup($options); } /** * Format the prompt string * * @return string */ protected function promptFormatted() { return $this->prompt . ' (use to select)'; } /** * Output the checkboxes and listen for any keystrokes */ protected function writeCheckboxes() { $this->updateCheckboxView(); $this->util->system->exec('stty -icanon'); $this->output->sameLine()->write($this->util->cursor->hide()); $this->listenForInput(); } /** * Listen for input and act on it */ protected function listenForInput() { while ($char = $this->reader->char(1)) { if ($this->handleCharacter($char)) { break; } $this->moveCursorToTop(); $this->updateCheckboxView(); } } /** * Take the appropriate action based on the input character, * returns whether to stop listening or not * * @param string $char * * @return bool */ protected function handleCharacter($char) { switch ($char) { case "\n": $this->output->sameLine()->write($this->util->cursor->defaultStyle()); $this->output->sameLine()->write("\e[0m"); return true; // Break the while loop as well case "\e": $this->handleAnsi(); break; case ' ': $this->checkboxes->toggleCurrent(); break; } return false; } /** * Move the cursor to the top of the option list */ protected function moveCursorToTop() { $output = $this->util->cursor->up($this->checkboxes->count() - 1); $output .= $this->util->cursor->startOfCurrentLine(); $this->output->sameLine()->write($output); } /** * Handle any ANSI characters */ protected function handleAnsi() { switch ($this->reader->char(2)) { // Up arrow case '[A': $this->checkboxes->setCurrent('previous'); break; // Down arrow case '[B': $this->checkboxes->setCurrent('next'); break; } } /** * Re-write the checkboxes based on the current objects */ protected function updateCheckboxView() { $this->checkboxes->util($this->util); $this->checkboxes->output($this->output); $this->checkboxes->parser($this->parser); $this->checkboxes->write(); } }