use std::time::{Duration, Instant};
use kas::class::HasString;
use kas::event::{Event, Handler, Manager, Response, VoidMsg};
use kas::macros::make_widget;
use kas::widget::{Frame, Label, TextButton, Window};
use kas::WidgetCore;
fn make_window() -> Box<dyn kas::Window> {
let stopwatch = make_widget! {
#[layout(row)]
#[widget(config=noauto)]
struct {
#[widget] display: impl HasString = Frame::new(Label::new("0.000".to_string())),
#[widget(handler = reset)] _ = TextButton::new_msg("&reset", ()),
#[widget(handler = start)] _ = TextButton::new_msg("&start / &stop", ()),
saved: Duration = Duration::default(),
start: Option<Instant> = None,
}
impl {
fn reset(&mut self, mgr: &mut Manager, _: ()) -> Response<VoidMsg> {
self.saved = Duration::default();
self.start = None;
*mgr |= self.display.set_str("0.000");
Response::None
}
fn start(&mut self, mgr: &mut Manager, _: ()) -> Response<VoidMsg> {
if let Some(start) = self.start {
self.saved += Instant::now() - start;
self.start = None;
} else {
self.start = Some(Instant::now());
mgr.update_on_timer(Duration::new(0, 0), self.id(), 0);
}
Response::None
}
}
impl kas::WidgetConfig {
fn configure(&mut self, mgr: &mut Manager) {
mgr.enable_alt_bypass(true);
}
}
impl Handler {
type Msg = VoidMsg;
fn handle(&mut self, mgr: &mut Manager, event: Event) -> Response<VoidMsg> {
match event {
Event::TimerUpdate(0) => {
if let Some(start) = self.start {
let dur = self.saved + (Instant::now() - start);
let text = format!("{}.{:03}", dur.as_secs(), dur.subsec_millis());
*mgr |= self.display.set_string(text);
mgr.update_on_timer(Duration::new(0, 1), self.id(), 0);
}
Response::None
}
_ => Response::Unhandled,
}
}
}
};
let mut window = Window::new("Stopwatch", stopwatch);
window.set_restrict_dimensions(true, true);
Box::new(window)
}
fn main() -> Result<(), kas_wgpu::Error> {
env_logger::init();
let theme = kas_theme::ShadedTheme::new()
.with_colours("dark")
.with_font_size(18.0);
kas_wgpu::Toolkit::new(theme)?
.with_boxed(make_window())?
.run()
}