Cleanup input

This commit is contained in:
Austen Adler 2023-09-18 22:11:16 -04:00
parent 9a12104044
commit 033d2d973a

View File

@ -1,4 +1,4 @@
use egui::{Button, Color32, FontId, Grid, Key, RichText, Rounding, Stroke, Vec2}; use egui::{Button, Color32, FontId, Frame, Grid, Key, Label, RichText, Rounding, Stroke, Vec2};
use rpn_rs::calc::{errors::CalculatorError, Calculator}; use rpn_rs::calc::{errors::CalculatorError, Calculator};
use tracing::{error, info}; use tracing::{error, info};
@ -19,6 +19,9 @@ pub struct TemplateApp {
#[serde(skip)] #[serde(skip)]
latest_error: Option<CalculatorError>, latest_error: Option<CalculatorError>,
#[serde(skip)]
error_state: ErrorState,
} }
impl Default for TemplateApp { impl Default for TemplateApp {
@ -28,6 +31,7 @@ impl Default for TemplateApp {
// Example stuff: // Example stuff:
label: "Hello World!".to_owned(), label: "Hello World!".to_owned(),
latest_error: None, latest_error: None,
error_state: ErrorState::default(),
} }
} }
} }
@ -47,11 +51,77 @@ impl TemplateApp {
Default::default() Default::default()
} }
fn calculator_input(&mut self, c: char, error_state: &mut ErrorState) { fn calculator_input(&mut self, c: char) {
if let Err(e) = self.calculator.take_input(c) { if let Err(e) = self.calculator.take_input(c) {
error_state.errored(e); self.error_state.errored(e);
} else { } else {
error_state.success(); self.error_state.success();
}
}
fn handle_input(&mut self, i: &egui::InputState) {
if i.events.is_empty() {
return;
}
for e in i.events.iter() {
match e {
egui::Event::Text(t) => {
self.calculator_input(t.chars().next().unwrap());
}
egui::Event::Key {
key: Key::ArrowLeft,
pressed: true,
..
} => {
self.calculator_input('<');
}
egui::Event::Key {
key: Key::ArrowRight,
pressed: true,
..
} => {
self.calculator_input('>');
}
egui::Event::Key {
key: Key::Enter,
pressed: true,
..
} => {
self.calculator_input(' ');
}
egui::Event::Copy => continue,
egui::Event::Cut => continue,
egui::Event::Paste(_) => continue,
egui::Event::Key {
key: _,
pressed: _,
repeat: _,
modifiers: _,
} => continue,
egui::Event::PointerMoved(_) => continue,
egui::Event::PointerButton {
pos: _,
button: _,
pressed: _,
modifiers: _,
} => continue,
egui::Event::PointerGone => continue,
egui::Event::Scroll(_) => continue,
egui::Event::Zoom(_) => continue,
egui::Event::CompositionStart => continue,
egui::Event::CompositionUpdate(_) => continue,
egui::Event::CompositionEnd(_) => continue,
egui::Event::Touch {
device_id: _,
id: _,
phase: _,
pos: _,
force: _,
} => continue,
egui::Event::AccessKitActionRequest(_) => continue,
}
} }
} }
} }
@ -84,153 +154,101 @@ impl eframe::App for TemplateApp {
}); });
}); });
let mut error_state = ErrorState::NoModify; self.error_state = ErrorState::default();
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {
ui.style_mut().spacing.button_padding = BUTTON_PADDING; ui.style_mut().spacing.button_padding = BUTTON_PADDING;
// The central panel the region left after adding TopPanel's and SidePanel's // The central panel the region left after adding TopPanel's and SidePanel's
ui.heading("rpn_rs_gui"); ui.input(|i: &egui::InputState| self.handle_input(i));
ui.hyperlink("https://gitea.austen-wares.com/stonewareslord/rpn_rs");
ui.input(|i| { Frame::none().fill(Color32::GREEN).show(ui, |ui| {
if i.events.is_empty() { ui.vertical(|ui| {
return; ui.heading("rpn_rs_gui");
} ui.hyperlink("https://gitea.austen-wares.com/stonewareslord/rpn_rs");
for e in i.events.iter() { // Buttons
match e { Grid::new("grid").spacing(BUTTON_SPACING).show(ui, |ui| {
egui::Event::Text(t) => { for row in BUTTON_LAYOUT.iter() {
self.calculator_input(t.chars().next().unwrap(), &mut error_state); for button in row.iter() {
} let label = RichText::new(button.value)
egui::Event::Key { .font(DEFAULT_FONT)
key: Key::ArrowLeft, .color(Color32::WHITE);
pressed: true, if ui
.. .add(
} => { Button::new(label)
self.calculator_input('<', &mut error_state); // .frame(false)
} .stroke(Stroke::NONE)
egui::Event::Key { .rounding(Rounding::none())
key: Key::ArrowRight, .fill(Color32::from_gray(0x12)),
pressed: true, )
.. .clicked()
} => { {
self.calculator_input('>', &mut error_state); info!("Clicked button {}", button.value);
} self.calculator_input(button.value);
egui::Event::Key { // if let Err(e) = self.calculator.take_input(button.value) {
key: Key::Enter, // error!("Calculator input error: {e:?}");
pressed: true, // self.latest_error = Some(e);
.. // fresh_error = true;
} => { // } else if !fresh_error {
self.calculator_input(' ', &mut error_state); // self.latest_error = None;
// }
}
}
ui.end_row();
} }
});
egui::Event::Copy => continue, // Stack
egui::Event::Cut => continue, // ui.add_sized( Vec2::new(ui.available_width(), ui.available_height()),
egui::Event::Paste(_) => continue, ui.add(Label::new(
egui::Event::Key { RichText::new(
key: _, self.calculator
pressed: _, .stack
repeat: _, .iter()
modifiers: _, .rev()
} => continue, .map(|e| e.to_string())
egui::Event::PointerMoved(_) => continue, .collect::<Vec<_>>()
egui::Event::PointerButton { .join("\n"),
pos: _, )
button: _, .background_color(egui::Color32::RED)
pressed: _,
modifiers: _,
} => continue,
egui::Event::PointerGone => continue,
egui::Event::Scroll(_) => continue,
egui::Event::Zoom(_) => continue,
egui::Event::CompositionStart => continue,
egui::Event::CompositionUpdate(_) => continue,
egui::Event::CompositionEnd(_) => continue,
egui::Event::Touch {
device_id: _,
id: _,
phase: _,
pos: _,
force: _,
} => continue,
egui::Event::AccessKitActionRequest(_) => continue,
}
}
});
Grid::new("grid").spacing(BUTTON_SPACING).show(ui, |ui| {
for row in BUTTON_LAYOUT.iter() {
for button in row.iter() {
let label = RichText::new(button.value).font(DEFAULT_FONT);
if ui
.add(
Button::new(label)
.stroke(Stroke::NONE)
.rounding(Rounding::none()),
)
.clicked()
{
info!("Clicked button {}", button.value);
self.calculator_input(button.value, &mut error_state);
// if let Err(e) = self.calculator.take_input(button.value) {
// error!("Calculator input error: {e:?}");
// self.latest_error = Some(e);
// fresh_error = true;
// } else if !fresh_error {
// self.latest_error = None;
// }
}
}
ui.end_row();
}
});
ui.label(
RichText::new(
self.calculator
.stack
.iter()
.rev()
.map(|e| e.to_string())
.collect::<Vec<_>>()
.join("\n"),
)
.background_color(egui::Color32::RED)
.font(DEFAULT_FONT)
.size(STACK_FONT_SIZE)
.color(Color32::WHITE),
);
egui::Frame::none()
.fill(egui::Color32::RED)
.inner_margin(5.0)
.stroke(Stroke::new(10.0, Color32::BLUE))
.show(ui, |ui| {
ui.label(
RichText::new(self.calculator.get_l())
.color(Color32::WHITE)
.font(DEFAULT_FONT),
);
});
match error_state {
ErrorState::NoModify => {}
ErrorState::Errored(e) => self.latest_error = Some(e),
ErrorState::Clear => self.latest_error = None,
}
if let Some(ref e) = self.latest_error {
ui.label(
RichText::new(e.to_string())
.font(DEFAULT_FONT) .font(DEFAULT_FONT)
.size(STACK_FONT_SIZE) .size(STACK_FONT_SIZE)
.color(Color32::RED), .color(Color32::WHITE),
); ));
}
egui::warn_if_debug_build(ui); egui::Frame::none()
.fill(egui::Color32::RED)
.inner_margin(5.0)
.stroke(Stroke::new(10.0, Color32::BLUE))
.show(ui, |ui| {
ui.label(
RichText::new(self.calculator.get_l())
.color(Color32::WHITE)
.font(DEFAULT_FONT),
);
});
// Reset the error state and update `self.latest_error` if required
match std::mem::take(&mut self.error_state) {
ErrorState::NoModify => {}
ErrorState::Errored(e) => self.latest_error = Some(e),
ErrorState::Clear => self.latest_error = None,
}
if let Some(ref e) = self.latest_error {
ui.label(
RichText::new(e.to_string())
.font(DEFAULT_FONT)
.size(STACK_FONT_SIZE)
.color(Color32::RED),
);
}
egui::warn_if_debug_build(ui);
});
})
}); });
// if false { // if false {
@ -257,49 +275,49 @@ impl CalculatorButton {
const BUTTON_LAYOUT: &[&[CalculatorButton]] = &[ const BUTTON_LAYOUT: &[&[CalculatorButton]] = &[
&[ &[
CalculatorButton::new('s', "Sin"), // CalculatorButton::new('s', "Sin"),
CalculatorButton::new('u', "Undo"), CalculatorButton::new('u', "Undo"),
CalculatorButton::new('U', "Redo"), CalculatorButton::new('U', "Redo"),
CalculatorButton::new('>', "Swap"), CalculatorButton::new('>', "Swap"),
// CalculatorButton::new('\\', "Drop"), CalculatorButton::new('@', "Drop"),
], ],
&[ &[
CalculatorButton::new('|', "AbsoluteValue"), // CalculatorButton::new('|', "AbsoluteValue"),
CalculatorButton::new('v', "Sqrt"), CalculatorButton::new('v', "Sqrt"),
CalculatorButton::new('^', "Pow"), CalculatorButton::new('^', "Pow"),
CalculatorButton::new('l', "Log"), CalculatorButton::new('l', "Log"),
CalculatorButton::new('L', "Ln"), CalculatorButton::new('L', "Ln"),
], ],
&[ &[
CalculatorButton::new('c', "Cos"), // CalculatorButton::new('c', "Cos"),
CalculatorButton::new('n', "Negate"), CalculatorButton::new('n', "Negate"),
CalculatorButton::new('%', "Modulo"), CalculatorButton::new('%', "Modulo"),
CalculatorButton::new('i', "Inverse"), CalculatorButton::new('i', "Inverse"),
CalculatorButton::new('/', "Divide"), CalculatorButton::new('/', "Divide"),
], ],
&[ &[
CalculatorButton::new('t', "Tan"), // CalculatorButton::new('t', "Tan"),
CalculatorButton::new('7', "7"), CalculatorButton::new('7', "7"),
CalculatorButton::new('8', "8"), CalculatorButton::new('8', "8"),
CalculatorButton::new('9', "9"), CalculatorButton::new('9', "9"),
CalculatorButton::new('*', "Multiply"), CalculatorButton::new('*', "Multiply"),
], ],
&[ &[
CalculatorButton::new('S', "ASin"), // CalculatorButton::new('S', "ASin"),
CalculatorButton::new('4', "4"), CalculatorButton::new('4', "4"),
CalculatorButton::new('5', "5"), CalculatorButton::new('5', "5"),
CalculatorButton::new('6', "6"), CalculatorButton::new('6', "6"),
CalculatorButton::new('-', "Subtract"), CalculatorButton::new('-', "Subtract"),
], ],
&[ &[
CalculatorButton::new('C', "ACos"), // CalculatorButton::new('C', "ACos"),
CalculatorButton::new('1', "1"), CalculatorButton::new('1', "1"),
CalculatorButton::new('2', "2"), CalculatorButton::new('2', "2"),
CalculatorButton::new('3', "3"), CalculatorButton::new('3', "3"),
CalculatorButton::new('+', "Add"), CalculatorButton::new('+', "Add"),
], ],
&[ &[
CalculatorButton::new('T', "ATan"), // CalculatorButton::new('T', "ATan"),
CalculatorButton::new('0', "0"), CalculatorButton::new('0', "0"),
CalculatorButton::new('\\', "Drop"), CalculatorButton::new('\\', "Drop"),
CalculatorButton::new('.', "Decimal"), CalculatorButton::new('.', "Decimal"),
@ -347,3 +365,8 @@ impl ErrorState {
} }
} }
} }
impl Default for ErrorState {
fn default() -> ErrorState {
ErrorState::NoModify
}
}