use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{Duration, Instant};
use kas::draw::Colour;
use kas::prelude::*;
use kas::widget::Window;
fn main() -> Result<(), kas_wgpu::Error> {
env_logger::init();
let theme = kas_theme::FlatTheme::new();
let toolkit = kas_wgpu::Toolkit::new(theme)?;
let proxy = toolkit.create_proxy();
let handle = UpdateHandle::new();
let colour = Arc::new(Mutex::new(Colour::grey(1.0)));
let colour2 = colour.clone();
thread::spawn(move || generate_colors(proxy, handle, colour2));
let widget = ColourSquare {
core: Default::default(),
colour,
handle,
};
let window = Window::new("Async event demo", widget);
toolkit.with(window)?.run()
}
#[derive(Debug, Widget)]
#[handler(handle = noauto)]
#[widget(config = noauto)]
struct ColourSquare {
#[widget_core]
core: CoreData,
colour: Arc<Mutex<Colour>>,
handle: UpdateHandle,
}
impl WidgetConfig for ColourSquare {
fn configure(&mut self, mgr: &mut Manager) {
mgr.update_on_handle(self.handle, self.id());
}
}
impl Layout for ColourSquare {
fn size_rules(&mut self, size_handle: &mut dyn SizeHandle, _: AxisInfo) -> SizeRules {
let factor = size_handle.scale_factor();
SizeRules::fixed_scaled(100.0, 10.0, factor)
}
fn draw(&self, draw_handle: &mut dyn DrawHandle, _: &ManagerState, _: bool) {
let (pass, offset, draw) = draw_handle.draw_device();
let col = *self.colour.lock().unwrap();
draw.rect(pass, (self.rect() + offset).into(), col);
}
}
impl Handler for ColourSquare {
type Msg = VoidMsg;
fn handle(&mut self, mgr: &mut Manager, event: Event) -> Response<VoidMsg> {
match event {
Event::HandleUpdate { .. } => {
mgr.redraw(self.id());
Response::None
}
_ => Response::Unhandled,
}
}
}
fn generate_colors(
proxy: kas_wgpu::ToolkitProxy,
handle: UpdateHandle,
colour: Arc<Mutex<Colour>>,
) {
let start_time = Instant::now();
loop {
let hue = (Instant::now() - start_time).as_secs_f32() / 5.0;
let f = |n| {
let k: f32 = (n + hue * 6.0) % 6.0;
1.0 - k.min(4.0 - k).clamp(0.0, 1.0)
};
let c = Colour::new(f(5.0), f(3.0), f(1.0));
*colour.lock().unwrap() = c;
if proxy.trigger_update(handle, 0).is_err() {
break;
}
thread::sleep(Duration::from_millis(20));
}
}