generated from ElnuDev/rust-project
Implement text typeout
This commit is contained in:
parent
20a8bf41b7
commit
61d99f7133
1 changed files with 83 additions and 15 deletions
|
@ -1,4 +1,6 @@
|
||||||
use std::path::PathBuf;
|
use std::{path::PathBuf, sync::{Arc, Mutex}};
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use eframe::egui;
|
use eframe::egui;
|
||||||
use egui::*;
|
use egui::*;
|
||||||
|
@ -23,38 +25,104 @@ pub fn run(file: PathBuf) -> Result<(), eframe::Error> {
|
||||||
struct App {
|
struct App {
|
||||||
state: State,
|
state: State,
|
||||||
text: String,
|
text: String,
|
||||||
|
chars: Arc<Mutex<usize>>,
|
||||||
|
typing_kill: Option<Arc<Mutex<bool>>>,
|
||||||
|
typing_done: Arc<Mutex<bool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl App {
|
impl App {
|
||||||
fn from_state(state: State) -> Self {
|
fn from_state(state: State) -> Self {
|
||||||
let mut app = Self {
|
Self {
|
||||||
state,
|
state,
|
||||||
text: "".to_owned(),
|
text: "".to_owned(),
|
||||||
};
|
chars: Arc::new(Mutex::new(0)),
|
||||||
app.next();
|
typing_kill: None,
|
||||||
app
|
typing_done: Arc::new(Mutex::new(true)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next(&mut self) {
|
fn next(&mut self, ctx: &Context) {
|
||||||
if let Some(Command::Say { name, text }) = self.state.next_command() {
|
if let Some(Command::Say { name, text }) = self.state.next_command() {
|
||||||
self.text = match name {
|
self.text = match name {
|
||||||
Some(name) => format!("{name}: {text}"),
|
Some(name) => format!("{name}: {text}"),
|
||||||
None => text,
|
None => text,
|
||||||
|
};
|
||||||
|
self.start_typing(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kill_typing(&mut self) {
|
||||||
|
if let Some(kill) = &self.typing_kill {
|
||||||
|
*kill.lock().unwrap() = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn interrupt_typing(&mut self) {
|
||||||
|
self.kill_typing();
|
||||||
|
*self.chars.lock().unwrap() = self.text.len();
|
||||||
|
*self.typing_done.lock().unwrap() = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn start_typing(&mut self, ctx: &Context) {
|
||||||
|
// Kill previous typing thread if exists
|
||||||
|
self.kill_typing();
|
||||||
|
|
||||||
|
*self.chars.lock().unwrap() = 0;
|
||||||
|
*self.typing_done.lock().unwrap() = false;
|
||||||
|
|
||||||
|
// Set up references to be passed into thread
|
||||||
|
let ctx = ctx.clone();
|
||||||
|
let kill = {
|
||||||
|
let kill = Arc::new(Mutex::new(false));
|
||||||
|
self.typing_kill = Some(kill.clone());
|
||||||
|
kill
|
||||||
|
};
|
||||||
|
let done = self.typing_done.clone();
|
||||||
|
let chars = self.chars.clone();
|
||||||
|
let len = self.text.len();
|
||||||
|
|
||||||
|
thread::spawn(move || {
|
||||||
|
let mut complete = false;
|
||||||
|
for i in 0..len {
|
||||||
|
if *kill.lock().unwrap() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*chars.lock().unwrap() = i;
|
||||||
|
ctx.request_repaint();
|
||||||
|
thread::sleep(Duration::from_millis(50));
|
||||||
|
complete = true;
|
||||||
}
|
}
|
||||||
|
if complete {
|
||||||
|
*done.lock().unwrap() = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_interaction(&mut self, ctx: &Context) {
|
||||||
|
if *self.typing_done.lock().unwrap() {
|
||||||
|
self.next(ctx);
|
||||||
|
} else {
|
||||||
|
self.interrupt_typing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default()
|
||||||
if ctx.input(|i|
|
.frame(Frame {
|
||||||
i.key_pressed(Key::Space)
|
fill: Color32::BLACK,
|
||||||
|| i.pointer.button_clicked(PointerButton::Primary)
|
inner_margin: Margin::same(32.0),
|
||||||
) {
|
..Default::default()
|
||||||
self.next();
|
})
|
||||||
}
|
.show(ctx, |ui| {
|
||||||
ui.label(&self.text);
|
if ctx.input(|i|
|
||||||
});
|
i.key_pressed(Key::Space)
|
||||||
|
|| i.pointer.button_clicked(PointerButton::Primary)
|
||||||
|
) {
|
||||||
|
self.handle_interaction(ctx);
|
||||||
|
}
|
||||||
|
ui.with_layout(egui::Layout::left_to_right(Align::Max), |ui| ui.heading(&self.text[0..*self.chars.lock().unwrap()]));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue