cbx function
Implementation
List<String> cbx(
String message,
List<String> keys,
List<String> startingKeys,
) {
final selected = startingKeys;
var hereIdx = 0;
var needsClear = false;
void writeIt() {
if (needsClear) {
for (var i = 0; i <= keys.length; i++) {
prompts.goUpOneLine();
prompts.clearLine();
}
} else {
needsClear = true;
}
print(message);
keys.asMap().forEach((index, option) {
final isSelected = selected.contains(option);
final isHere = index == hereIdx;
final text = ' ${isSelected ? '♦' : '♢'} $option';
final color = isHere ? ansi.cyan : ansi.darkGray;
print(color.wrap(text));
});
}
final oldEchoMode = stdin.echoMode;
final oldLineMode = stdin.lineMode;
while (true) {
int ch;
writeIt();
try {
stdin.lineMode = stdin.echoMode = false;
ch = stdin.readByteSync();
if (ch == ascii.$esc) {
ch = stdin.readByteSync();
if (ch == ascii.$lbracket) {
ch = stdin.readByteSync();
if (ch == ascii.$A) {
// Up key
hereIdx--;
if (hereIdx < 0) {
hereIdx = keys.length - 1;
}
writeIt();
} else if (ch == ascii.$B) {
// Down key
hereIdx++;
if (hereIdx >= keys.length) {
hereIdx = 0;
}
writeIt();
}
}
} else if (ch == ascii.$lf) {
// Enter key pressed - submit
return selected;
} else if (ch == ascii.$space) {
// Space key pressed - selected/unselect
final key = keys[hereIdx];
if (selected.contains(key)) {
selected.remove(key);
} else {
selected.add(key);
}
writeIt();
}
} finally {
stdin.lineMode = oldLineMode;
stdin.echoMode = oldEchoMode;
}
}
}