- fully implemented dialogs
- added a scroll feature to grapher.rs - fixed the cosine implementation as it was incorrect before.
This commit is contained in:
@@ -48,6 +48,8 @@ pub enum KeyStroke {
|
||||
Backspace,
|
||||
Left,
|
||||
Right,
|
||||
Up,
|
||||
Down,
|
||||
None,
|
||||
Enter
|
||||
}
|
||||
@@ -66,6 +68,8 @@ impl KeyStroke {
|
||||
KeyCode::Backspace => KeyStroke::Backspace,
|
||||
KeyCode::ArrowLeft => KeyStroke::Left,
|
||||
KeyCode::ArrowRight => KeyStroke::Right,
|
||||
KeyCode::ArrowUp => KeyStroke::Up,
|
||||
KeyCode::ArrowDown => KeyStroke::Down,
|
||||
KeyCode::Enter => KeyStroke::Enter,
|
||||
_ => KeyStroke::None,
|
||||
}
|
||||
|
||||
@@ -40,20 +40,27 @@ fn factorial(x: f64) -> Result<f64, String> {
|
||||
|
||||
fn cos(mut x: f64) -> Result<f64, String> {
|
||||
while x > PI {
|
||||
x -= PI;
|
||||
x -= 2.0*PI;
|
||||
}
|
||||
while x < -PI {
|
||||
x += 2.0*PI;
|
||||
}
|
||||
|
||||
let res = 1.0 - trig_term(x, 2) + trig_term(x, 4) - trig_term(x, 6) + trig_term(x, 8) - trig_term(x, 10);
|
||||
if res >= -1.0 && res <= 1.0 {
|
||||
Ok(res)
|
||||
} else {
|
||||
panic!("something is very wrong with the cos function : {}", res);
|
||||
Ok(res)
|
||||
// panic!("something is very wrong with the cos function : {}", res);
|
||||
}
|
||||
}
|
||||
|
||||
fn sin(mut x: f64) -> Result<f64, String> {
|
||||
while x > PI {
|
||||
x -= PI;
|
||||
x -= 2.0*PI;
|
||||
}
|
||||
while x < -PI {
|
||||
x += 2.0*PI;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +68,8 @@ fn sin(mut x: f64) -> Result<f64, String> {
|
||||
if res >= -1.0 && res <= 1.0 {
|
||||
Ok(res)
|
||||
} else {
|
||||
panic!("something is very wrong with the sin function: {}", res);
|
||||
Ok(res)
|
||||
// panic!("something is very wrong with the sin function: {}", res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+22
-16
@@ -61,7 +61,7 @@ impl Application for Grapher {
|
||||
|
||||
if args.len() > 0 {
|
||||
let equation: String = args.into_iter().collect();
|
||||
self.graph_equation(equation);
|
||||
self.graph_equation(equation, (0, 0));
|
||||
|
||||
if let Ok(frame) = self.render() {
|
||||
frame.write_to_screen().map_err(|_| Error::ApplicationError(String::from("failed to write to screen")))?;
|
||||
@@ -93,52 +93,58 @@ impl Application for Grapher {
|
||||
|
||||
let mut commandresult = String::new();
|
||||
|
||||
let mut offset_x: i64 = 0;
|
||||
let mut offset_y: i64 = 0;
|
||||
|
||||
let mut rerender = true;
|
||||
|
||||
while let c = Stdin::keystroke().await {
|
||||
|
||||
let mut entry_widget = container.elements.get("entry_box").unwrap();
|
||||
let mut entry = entry_widget.fetch::<CgLineEdit>().unwrap();
|
||||
|
||||
rerender = true;
|
||||
match c {
|
||||
KeyStroke::Char('\n') => {
|
||||
commandresult = entry.text.iter().collect();
|
||||
entry.clear();
|
||||
offset_x = 0;
|
||||
offset_y = 0;
|
||||
},
|
||||
KeyStroke::Char(Stdin::BACKSPACE) => {
|
||||
rerender = false;
|
||||
entry.backspace()
|
||||
},
|
||||
KeyStroke::Char('`') => {
|
||||
break;
|
||||
}
|
||||
KeyStroke::Char(c) => entry.write_char(c),
|
||||
KeyStroke::Left => entry.move_cursor(false),
|
||||
KeyStroke::Right => entry.move_cursor(true),
|
||||
KeyStroke::Left => offset_x -= 1,
|
||||
KeyStroke::Right => offset_x += 1,
|
||||
KeyStroke::Up => offset_y -= 1,
|
||||
KeyStroke::Down => offset_y += 1,
|
||||
KeyStroke::Alt => break,
|
||||
_ => {}
|
||||
_ => {
|
||||
rerender = false;
|
||||
}
|
||||
}
|
||||
|
||||
if commandresult.len() > 0 {
|
||||
if commandresult.len() > 0 && rerender {
|
||||
self.reset_frame();
|
||||
self.graph_equation(commandresult.clone());
|
||||
|
||||
self.graph_equation(commandresult.clone(), (offset_x, offset_y));
|
||||
let self_widget = container.elements.get("grapher").unwrap();
|
||||
self_widget.update(self.clone());
|
||||
|
||||
commandresult.clear();
|
||||
}
|
||||
|
||||
serial_println!("{:?}", entry.text);
|
||||
entry_widget.update(entry);
|
||||
|
||||
if let Ok(frame) = container.render() {
|
||||
|
||||
let self_widget = container.elements.get("grapher").unwrap();
|
||||
let self_clone = self_widget.fetch::<Grapher>().unwrap();
|
||||
serial_println!("{:?}", self_clone.points);
|
||||
|
||||
let entry = container.elements.get("entry_box").unwrap();
|
||||
let entry_clone = entry.fetch::<CgLineEdit>().unwrap();
|
||||
serial_println!("{:?}", entry_clone.text);
|
||||
|
||||
|
||||
frame.write_to_screen().map_err(|_| Error::ApplicationError(String::from("failed to write to screen")))?;
|
||||
}
|
||||
@@ -152,7 +158,7 @@ impl Application for Grapher {
|
||||
|
||||
impl Grapher {
|
||||
|
||||
fn graph_equation(&mut self, equation: String) {
|
||||
fn graph_equation(&mut self, equation: String, offsets: (i64, i64)) {
|
||||
|
||||
let cal = calc::Calculator::new();
|
||||
for x in -4000..4000 {
|
||||
@@ -160,7 +166,7 @@ impl Grapher {
|
||||
|
||||
let new_eq = equation.chars().map(|c| {
|
||||
match c {
|
||||
'x' => format!("({})", x),
|
||||
'x' => format!("({})", x + offsets.0 as f64),
|
||||
'e' => format!("({})", E),
|
||||
'π' => format!("({})", PI),
|
||||
_ => c.to_string(),
|
||||
@@ -171,7 +177,7 @@ impl Grapher {
|
||||
if let Ok(y) = fx {
|
||||
self.render_point(PointF64 {
|
||||
x,
|
||||
y,
|
||||
y: y + offsets.1 as f64,
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
+102
-82
@@ -2,24 +2,35 @@ use async_trait::async_trait;
|
||||
use lazy_static::lazy_static;
|
||||
use spin::Mutex;
|
||||
|
||||
use alloc::{boxed::Box, string::{String, ToString}, vec, vec::Vec};
|
||||
use alloc::{boxed::Box, format, string::{String, ToString}, vec, vec::Vec};
|
||||
use futures_util::TryFutureExt;
|
||||
use vga::writers::{GraphicsWriter, PrimitiveDrawing};
|
||||
|
||||
use crate::{print, printerr, println, serial_println, std, std::application::{Application, Error, Exit}, user::bin::*};
|
||||
use crate::std::frame::{Dimensions, Position, ColorCode};
|
||||
use crate::std::io::{Color, write, Screen, Stdin, Serial, KeyStroke};
|
||||
use crate::std::random::Random;
|
||||
use crate::std::time::timer;
|
||||
use crate::user::bin::gigachad_detector::GigachadDetector;
|
||||
use crate::user::bin::grapher::Grapher;
|
||||
use crate::user::lib::libgui::{
|
||||
cg_core::{CgComponent, CgTextEdit},
|
||||
cg_widgets::{CgTextBox, CgContainer, CgIndicatorBar, CgIndicatorWidget, CgLabel, CgStatusBar},
|
||||
cg_inputs::CgLineEdit,
|
||||
use crate::{
|
||||
print,
|
||||
printerr,
|
||||
println,
|
||||
serial_println,
|
||||
};
|
||||
|
||||
use crate::std::{
|
||||
application::{Application, Error, Exit},
|
||||
time::{timer, wait},
|
||||
random::Random,
|
||||
io::{
|
||||
Color, write, Screen, Stdin, Serial, KeyStroke
|
||||
},
|
||||
frame::{Dimensions, Position, ColorCode},
|
||||
};
|
||||
|
||||
use crate::user::{
|
||||
lib::libgui::{
|
||||
cg_core::{CgComponent, CgTextEdit, CgKeyboardCapture, CgTextInput, Widget},
|
||||
cg_widgets::{CgTextBox, CgContainer, CgLabel, CgStatusBar, CgDialog},
|
||||
cg_inputs::CgLineEdit,
|
||||
},
|
||||
bin::*,
|
||||
};
|
||||
use crate::user::lib::libgui::cg_core::{CgKeyboardCapture, CgTextInput, Widget};
|
||||
use crate::user::lib::libgui::cg_widgets::{CgDialog, CgDialogType};
|
||||
|
||||
lazy_static! {
|
||||
pub static ref CMD: Mutex<CommandHandler> = Mutex::new(CommandHandler::new());
|
||||
@@ -120,12 +131,10 @@ async fn exec() -> Result<(), Error> {
|
||||
mode.draw_line((80, 60), (80, 420), Color16::Cyan);
|
||||
}
|
||||
"graph" => {
|
||||
let mut grapher = Grapher::new();
|
||||
grapher.run(args).await?;
|
||||
grapher::Grapher::new().run(args).await?;
|
||||
}
|
||||
"snake" => {
|
||||
let mut game = snake::Game::new();
|
||||
game.run(args).await?;
|
||||
snake::Game::new().run(args).await?;
|
||||
}
|
||||
"asteroids" => {
|
||||
let mut asteroid_game = asteroids::Game::new();
|
||||
@@ -145,13 +154,11 @@ async fn exec() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
"gigachad?" => {
|
||||
let mut gigachad_detector = GigachadDetector::new();
|
||||
gigachad_detector.run(args).await?;
|
||||
let mut detector = gigachad_detector::GigachadDetector::new();
|
||||
detector.run(args).await?;
|
||||
}
|
||||
|
||||
"wait" => {
|
||||
use std::time::wait;
|
||||
|
||||
if args.len() != 1 {
|
||||
return Err(Error::CommandFailed("exactly one argument must be provided".to_string()))
|
||||
}
|
||||
@@ -260,11 +267,25 @@ async fn setup_ui() {
|
||||
_ => (x, Exit::None),
|
||||
}};
|
||||
|
||||
let options = vec![String::from("Nerd Detected"), String::from("Ok Boomer"), String::from("Idefksda")];
|
||||
|
||||
let mut dialog = CgDialog::new(
|
||||
String::from("i'd just like to interject for a moment"),
|
||||
String::from("The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called Linux distributions are really distributions of GNU/Linux!"),
|
||||
// CgDialog::Type::Selection(vec![String::from("Shut Up Nerd"), String::from("Ok Boomer"), String::from("Nice")]),
|
||||
CgDialogType::Information
|
||||
CgDialog::Type::Selection(options.clone()),
|
||||
// CgDialogType::Information
|
||||
// CgDialogType::Confirmation
|
||||
);
|
||||
|
||||
if let Ok(frame) = dialog.render() {
|
||||
frame.write_to_screen().unwrap();
|
||||
}
|
||||
let (_, x) = dialog.keyboard_capture(exit, None).await.unwrap();
|
||||
|
||||
let mut dialog = CgDialog::new(
|
||||
String::from("i'd just like to interject for a moment"),
|
||||
format!("Your response was [{}]", options[x]),
|
||||
CgDialog::Type::Information,
|
||||
);
|
||||
|
||||
if let Ok(frame) = dialog.render() {
|
||||
@@ -273,64 +294,63 @@ async fn setup_ui() {
|
||||
dialog.keyboard_capture(exit, None).await.unwrap();
|
||||
|
||||
|
||||
serial_println!("idk");
|
||||
let label= Widget::insert(CgLabel::new(
|
||||
String::from("test label"),
|
||||
Position::new(1, 1),
|
||||
40,
|
||||
false,
|
||||
));
|
||||
|
||||
let textbox = Widget::insert(CgTextBox::new(
|
||||
String::from("i'd just like to interject for a moment"),
|
||||
String::from("I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called Linux, and many of its users are not aware that it is basically the GNU system, developed by the GNU Project. There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called Linux distributions are really distributions of GNU/Linux!"),
|
||||
Position::new(2, 5),
|
||||
Dimensions::new(40, 12),
|
||||
true,
|
||||
));
|
||||
|
||||
let textedit = Widget::insert(CgLineEdit::new(
|
||||
Position::new(10, 20),
|
||||
60,
|
||||
String::from("enter text here >"),
|
||||
));
|
||||
|
||||
let statusbar = Widget::insert(CgStatusBar::new(Position::new(0, 0), Dimensions::new(80, 1)));
|
||||
let container = Widget::insert({
|
||||
let mut container = CgContainer::new(
|
||||
Position::new(0, 0),
|
||||
Dimensions::new(80, 25),
|
||||
true,
|
||||
);
|
||||
container.insert("textbox", textbox);
|
||||
container.insert("label", label);
|
||||
container.insert("textedit", textedit);
|
||||
container.insert("statusbar", statusbar);
|
||||
container
|
||||
});
|
||||
|
||||
if let Ok(frame) = container.render() {
|
||||
frame.write_to_screen().unwrap();
|
||||
} else {
|
||||
serial_println!("failed to write to screen");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
let container_copy = container.fetch::<CgContainer>().unwrap();
|
||||
let entry_ref = container_copy.fetch("textedit").unwrap();
|
||||
let mut entry = entry_ref.fetch::<CgLineEdit>().unwrap();
|
||||
|
||||
while let Ok((string, false)) = entry.input(exit, &entry_ref, &container).await {
|
||||
let textbox_ref = container_copy.fetch("textbox").unwrap();
|
||||
let mut textbox = textbox_ref.fetch::<CgTextBox>().unwrap();
|
||||
textbox.content = string;
|
||||
textbox_ref.update(textbox);
|
||||
if let Ok(frame) = container.render() {
|
||||
frame.write_to_screen().unwrap();
|
||||
}
|
||||
}
|
||||
// let label= Widget::insert(CgLabel::new(
|
||||
// String::from("test label"),
|
||||
// Position::new(1, 1),
|
||||
// 40,
|
||||
// false,
|
||||
// ));
|
||||
//
|
||||
// let textbox = Widget::insert(CgTextBox::new(
|
||||
// String::from("i'd just like to interject for a moment"),
|
||||
// String::from("I'd just like to interject for a moment. What you're referring to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it, GNU plus Linux. Linux is not an operating system unto itself, but rather another free component of a fully functioning GNU system made useful by the GNU corelibs, shell utilities and vital system components comprising a full OS as defined by POSIX. Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called Linux, and many of its users are not aware that it is basically the GNU system, developed by the GNU Project. There really is a Linux, and these people are using it, but it is just a part of the system they use. Linux is the kernel: the program in the system that allocates the machine's resources to the other programs that you run. The kernel is an essential part of an operating system, but useless by itself; it can only function in the context of a complete operating system. Linux is normally used in combination with the GNU operating system: the whole system is basically GNU with Linux added, or GNU/Linux. All the so-called Linux distributions are really distributions of GNU/Linux!"),
|
||||
// Position::new(2, 5),
|
||||
// Dimensions::new(40, 12),
|
||||
// true,
|
||||
// ));
|
||||
//
|
||||
// let textedit = Widget::insert(CgLineEdit::new(
|
||||
// Position::new(10, 20),
|
||||
// 60,
|
||||
// String::from("enter text here >"),
|
||||
// ));
|
||||
//
|
||||
// let statusbar = Widget::insert(CgStatusBar::new(Position::new(0, 0), Dimensions::new(80, 1)));
|
||||
// let container = Widget::insert({
|
||||
// let mut container = CgContainer::new(
|
||||
// Position::new(0, 0),
|
||||
// Dimensions::new(80, 25),
|
||||
// true,
|
||||
// );
|
||||
// container.insert("textbox", textbox);
|
||||
// container.insert("label", label);
|
||||
// container.insert("textedit", textedit);
|
||||
// container.insert("statusbar", statusbar);
|
||||
// container
|
||||
// });
|
||||
//
|
||||
// if let Ok(frame) = container.render() {
|
||||
// frame.write_to_screen().unwrap();
|
||||
// } else {
|
||||
// serial_println!("failed to write to screen");
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// let container_copy = container.fetch::<CgContainer>().unwrap();
|
||||
// let entry_ref = container_copy.fetch("textedit").unwrap();
|
||||
// let mut entry = entry_ref.fetch::<CgLineEdit>().unwrap();
|
||||
//
|
||||
// while let Ok((string, false)) = entry.input(exit, &entry_ref, &container).await {
|
||||
// let textbox_ref = container_copy.fetch("textbox").unwrap();
|
||||
// let mut textbox = textbox_ref.fetch::<CgTextBox>().unwrap();
|
||||
// textbox.content = string;
|
||||
// textbox_ref.update(textbox);
|
||||
// if let Ok(frame) = container.render() {
|
||||
// frame.write_to_screen().unwrap();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ pub trait CgTextInput: CgTextEdit {
|
||||
|
||||
#[async_trait]
|
||||
pub trait CgKeyboardCapture: CgComponent {
|
||||
async fn keyboard_capture(&mut self, break_condition: fn(KeyStroke) -> (KeyStroke, Exit), app: Option<&Widget>) -> Result<bool, RenderError>;
|
||||
async fn keyboard_capture(&mut self, break_condition: fn(KeyStroke) -> (KeyStroke, Exit), app: Option<&Widget>) -> Result<(Exit, usize), RenderError>;
|
||||
}
|
||||
|
||||
static ID_COUNTER: Mutex<usize> = Mutex::new(0);
|
||||
|
||||
@@ -359,7 +359,8 @@ pub struct CgDialog {
|
||||
content: String,
|
||||
accepted: bool,
|
||||
outlined: bool,
|
||||
dialog_class: CgDialogType,
|
||||
pub dialog_class: CgDialogType,
|
||||
pub selected_idx: usize,
|
||||
}
|
||||
|
||||
impl CgDialog {
|
||||
@@ -371,6 +372,7 @@ impl CgDialog {
|
||||
accepted: false,
|
||||
outlined: true,
|
||||
dialog_class: class,
|
||||
selected_idx: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -405,7 +407,7 @@ impl CgComponent for CgDialog {
|
||||
return Err(RenderError::OutOfBounds(true, true));
|
||||
}
|
||||
};
|
||||
height = (self.content.len() as f32 * 1.25 / (width as f32)) as usize;
|
||||
height = (self.content.len() as f32 * 1.25 / (width as f32)) as usize + 1;
|
||||
|
||||
// account for borders
|
||||
width += 4;
|
||||
@@ -426,7 +428,7 @@ impl CgComponent for CgDialog {
|
||||
frame.place_child_element(&title.render().unwrap());
|
||||
|
||||
|
||||
let (mut x, mut y) = (2, 5); // top left of the text box
|
||||
let (mut x, mut y) = (2, 4); // top left of the text box
|
||||
for word in self.content.split(' ') {
|
||||
if word.len() + 1 > 1 + width - 4 - x { // adding a +1 on both sides accounts for the possible negative value at the end of the line, avoiding integer underflow.
|
||||
if word.len() <= width - 4 {
|
||||
@@ -459,34 +461,50 @@ impl CgComponent for CgDialog {
|
||||
"[ Ok ]".chars().enumerate().for_each(|(i, c)| {
|
||||
frame.write(Position::new(button_x_offset + i, height - 3), ColouredChar {
|
||||
character: c,
|
||||
colour: ColorCode::new(Color::Black, Color::White),
|
||||
colour: ColorCode::new(Color::Cyan, Color::Black),
|
||||
});
|
||||
})
|
||||
}
|
||||
CgDialogType::Confirmation => {
|
||||
let button_x_offset = (width - 22) / 2;
|
||||
let button_y_offset = height - 3;
|
||||
"[ Confirm ]".chars().enumerate().for_each(|(i, c)| {
|
||||
frame.write(Position::new(button_x_offset + i, button_y_offset), ColouredChar {
|
||||
character: c,
|
||||
colour: ColorCode::new(Color::Black, Color::White),
|
||||
});
|
||||
});
|
||||
"[ Cancel ]".chars().enumerate().for_each(|(i, c)| {
|
||||
frame.write(Position::new(button_x_offset + i, button_y_offset + 1), ColouredChar {
|
||||
character: c,
|
||||
colour: ColorCode::new(Color::Black, Color::White),
|
||||
});
|
||||
});
|
||||
let button_fmt = ["Cancel", "Confirm"]
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
if i == self.selected_idx {
|
||||
format!("[{}] ", s).chars().map(|c| ColouredChar {
|
||||
character: c,
|
||||
colour: ColorCode::new(Color::Cyan, Color::Black),
|
||||
}).collect::<Vec<ColouredChar>>()
|
||||
} else {
|
||||
format!("[{}] ", s).chars().map(|c| ColouredChar::new(c)).collect()
|
||||
}
|
||||
}).flatten()
|
||||
.collect::<Vec<ColouredChar>>();
|
||||
|
||||
let button_x_offset = (width - button_fmt.len()) / 2;
|
||||
button_fmt.into_iter().enumerate().for_each(|(i, c)| {
|
||||
frame.write(Position::new(button_x_offset + i, height - 3), c);
|
||||
})
|
||||
},
|
||||
CgDialogType::Selection(options) => {
|
||||
let button_string = options.iter().map(|option| format!("[ {} ] ", option)).collect::<String>();
|
||||
let button_x_offset = (width - button_string.len()) / 2;
|
||||
button_string.chars().enumerate().for_each(|(i, c)| {
|
||||
frame.write(Position::new(button_x_offset + i, height - 3), ColouredChar {
|
||||
character: c,
|
||||
colour: ColorCode::new(Color::Black, Color::White),
|
||||
});
|
||||
let button_fmt = options
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, s)| {
|
||||
if i == self.selected_idx {
|
||||
format!("[{}] ", s).chars().map(|c| ColouredChar {
|
||||
character: c,
|
||||
colour: ColorCode::new(Color::Cyan, Color::Black),
|
||||
}).collect::<Vec<ColouredChar>>()
|
||||
} else {
|
||||
format!("[{}] ", s).chars().map(|c| ColouredChar::new(c)).collect()
|
||||
}
|
||||
}).flatten()
|
||||
.collect::<Vec<ColouredChar>>();
|
||||
|
||||
let button_x_offset = (width - button_fmt.len()) / 2;
|
||||
button_fmt.into_iter().enumerate().for_each(|(i, c)| {
|
||||
frame.write(Position::new(button_x_offset + i, height - 3), c);
|
||||
})
|
||||
}
|
||||
};
|
||||
@@ -502,14 +520,46 @@ impl CgComponent for CgDialog {
|
||||
|
||||
#[async_trait]
|
||||
impl CgKeyboardCapture for CgDialog {
|
||||
async fn keyboard_capture(&mut self, break_condition: fn(KeyStroke) -> (KeyStroke, Exit), app: Option<&Widget>) -> Result<bool, RenderError> {
|
||||
async fn keyboard_capture(&mut self, break_condition: fn(KeyStroke) -> (KeyStroke, Exit), app: Option<&Widget>) -> Result<(Exit, usize), RenderError> {
|
||||
loop {
|
||||
let k = break_condition(Stdin::keystroke().await);
|
||||
serial_println!("captured: {:?}", k.0);
|
||||
match k {
|
||||
(KeyStroke::Char('\n'), _) => {
|
||||
return Ok(true)
|
||||
(_, Exit::Exit) => { // this handles the "exit" keybind given to the function
|
||||
return Ok((Exit::Exit, 0))
|
||||
}
|
||||
(KeyStroke::Char('\n'), _) => { // return the chosen option
|
||||
return Ok((Exit::None, self.selected_idx))
|
||||
},
|
||||
(KeyStroke::Left, _) => {
|
||||
if self.selected_idx > 0 {
|
||||
self.selected_idx -= 1;
|
||||
if let Ok(frame) = self.render() {
|
||||
frame.write_to_screen()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
(KeyStroke::Right, _) => {
|
||||
match &self.dialog_class {
|
||||
CgDialogType::Information => continue,
|
||||
CgDialogType::Confirmation => {
|
||||
if self.selected_idx == 0 {
|
||||
self.selected_idx += 1;
|
||||
if let Ok(frame) = self.render() {
|
||||
frame.write_to_screen()?;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
CgDialogType::Selection(options) => {
|
||||
if self.selected_idx < options.len() - 1 {
|
||||
self.selected_idx += 1;
|
||||
if let Ok(frame) = self.render() {
|
||||
frame.write_to_screen()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user