Skip to content

Instantly share code, notes, and snippets.

@sdondley
Created June 18, 2022 20:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sdondley/a5bdfc368f0e81a96a90eac887d9b7cf to your computer and use it in GitHub Desktop.
Save sdondley/a5bdfc368f0e81a96a90eac887d9b7cf to your computer and use it in GitHub Desktop.
use v6.d;
unit module Simple;
class Menu { ... }
class Option {
has Str $.display-string is required;
has Int $.option-number;
has Menu $.submenu is rw;
has &.action;
}
role Option-group {
my %counters;
has %.options;
method display-group() {
my $format = self.option-format ~ $.option-separator;
for self.options.sort>>.kv -> ($k, $v) {
printf $format, $k, $v.display-string;
}
}
method add-option(Str:D :$display-string, Menu :$submenu, :&action) {
my $counter = ++%counters{self.menuID};
self.options{$counter} = Option.new(:&action, :$submenu, :$display-string, option-number => $counter);
return self;
}
method add-options(List:D $options where { $options.all ~~ Str }) {
for $options.all -> $display-string {
self.add-option(:$display-string);
}
return self;
}
method get-option(Str:D $option-number) {
self.options{$option-number};
}
method option-count() {
return %counters{self.menuID};
}
multi method add-submenu(Menu:D $menu) {
%.options{%counters{self.menID}}.submenu = $menu;
}
multi method add-submenu(Menu:D $menu, Int:D $option-number) {
%.options{$option-number}.submenu = $menu;
}
}
class Menu does Option-group is export {
my $ID = 0;
has Int $.menuID = ++$ID;
has Str $.option-format is rw = "%d - %s";
has Str() $.selection is rw;
has Str() $.validated-selection is rw = Nil;
has Str $.option-separator is rw = "\n";
has Str @.prompt = "\nMake selection: ";
has Str $.error-msg = "\nSorry, invalid entry. Try again. ";
method display() {
self.display-group;
self.display-prompt;
}
method display-prompt() {
print self.prompt;
}
method get-selection() {
self.selection = getc();
}
method validate-selection( --> Bool) {
self.validated-selection = Nil;
my $valid = False;
try { $valid = self.selection > 0 && !(self.selection > self.option-count) };
return $valid;
}
method process-selection() {
if !self.validate-selection {
self.error-msg.say;
self.display-prompt;
}
self.validated-selection = self.selection;
self.selection = Nil;
}
multi method menu-execute() {
self.display;
self.get-selection if !self.selection;
self.process-selection;
my $option = self.get-option(self.validated-selection);
if $option.action {
$option.action();
}
return $option.submenu ?? $option.submenu.menu-execute !! $option;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment