#![windows_subsystem = "windows"]
use std::time::Duration;
use druid::widget::prelude::*;
use druid::widget::BackgroundBrush;
use druid::{AppLauncher, Color, LocalizedString, Point, TimerToken, WidgetPod, WindowDesc};
static TIMER_INTERVAL: Duration = Duration::from_millis(10);
struct TimerWidget {
timer_id: TimerToken,
simple_box: WidgetPod<u32, SimpleBox>,
pos: Point,
}
impl TimerWidget {
fn adjust_box_pos(&mut self, container_size: Size) {
let box_size = self.simple_box.layout_rect().size();
self.pos.x += 2.;
if self.pos.x + box_size.width > container_size.width {
self.pos.x = 0.;
self.pos.y += box_size.height;
if self.pos.y + box_size.height > container_size.height {
self.pos.y = 0.;
}
}
}
}
impl Widget<u32> for TimerWidget {
fn event(&mut self, ctx: &mut EventCtx, event: &Event, data: &mut u32, env: &Env) {
match event {
Event::WindowConnected => {
self.timer_id = ctx.request_timer(TIMER_INTERVAL);
}
Event::Timer(id) => {
if *id == self.timer_id {
self.adjust_box_pos(ctx.size());
ctx.request_layout();
self.timer_id = ctx.request_timer(TIMER_INTERVAL);
}
}
_ => (),
}
self.simple_box.event(ctx, event, data, env);
}
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, data: &u32, env: &Env) {
self.simple_box.lifecycle(ctx, event, data, env);
}
fn update(&mut self, ctx: &mut UpdateCtx, _old_data: &u32, data: &u32, env: &Env) {
self.simple_box.update(ctx, data, env);
}
fn layout(&mut self, ctx: &mut LayoutCtx, bc: &BoxConstraints, data: &u32, env: &Env) -> Size {
self.simple_box.layout(ctx, &bc.loosen(), data, env);
self.simple_box.set_origin(ctx, self.pos);
bc.constrain((500.0, 500.0))
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &u32, env: &Env) {
self.simple_box.paint(ctx, data, env);
}
}
struct SimpleBox;
impl Widget<u32> for SimpleBox {
fn event(&mut self, _ctx: &mut EventCtx, _event: &Event, _data: &mut u32, _env: &Env) {}
fn lifecycle(&mut self, ctx: &mut LifeCycleCtx, event: &LifeCycle, _data: &u32, _env: &Env) {
if let LifeCycle::HotChanged(_) = event {
ctx.request_paint();
}
}
fn update(&mut self, _ctx: &mut UpdateCtx, _old_data: &u32, _data: &u32, _env: &Env) {}
fn layout(
&mut self,
_ctx: &mut LayoutCtx,
bc: &BoxConstraints,
_data: &u32,
_env: &Env,
) -> Size {
bc.constrain((50.0, 50.0))
}
fn paint(&mut self, ctx: &mut PaintCtx, data: &u32, env: &Env) {
let mut background = if ctx.is_hot() {
BackgroundBrush::Color(Color::rgb8(200, 55, 55))
} else {
BackgroundBrush::Color(Color::rgb8(30, 210, 170))
};
background.paint(ctx, data, env);
}
}
pub fn main() {
let window = WindowDesc::new(TimerWidget {
timer_id: TimerToken::INVALID,
simple_box: WidgetPod::new(SimpleBox),
pos: Point::ZERO,
})
.with_min_size((200., 200.))
.title(LocalizedString::new("timer-demo-window-title").with_placeholder("Look at it go!"));
AppLauncher::with_window(window)
.log_to_console()
.launch(0u32)
.expect("launch failed");
}