use druid::{ kurbo::Line, widget::{FillStrat, SvgData}, Color, Data, Rect, RenderContext, Widget, }; pub struct ToolbarItem { icon: SvgData, } impl Widget for ToolbarItem { fn event( &mut self, _ctx: &mut druid::EventCtx, _event: &druid::Event, _data: &mut T, _env: &druid::Env, ) { } fn lifecycle( &mut self, ctx: &mut druid::LifeCycleCtx, event: &druid::LifeCycle, _data: &T, _env: &druid::Env, ) { if let druid::LifeCycle::HotChanged(true) = event { ctx.request_paint(); } } fn update(&mut self, _ctx: &mut druid::UpdateCtx, _old_data: &T, _data: &T, _env: &druid::Env) { } fn layout( &mut self, _ctx: &mut druid::LayoutCtx, bc: &druid::BoxConstraints, _data: &T, _env: &druid::Env, ) -> druid::Size { druid::Size::new(bc.max().height * 1.6, bc.max().height) } fn paint(&mut self, ctx: &mut druid::PaintCtx, _data: &T, _env: &druid::Env) { let bg_rect = Rect::ZERO.with_size(ctx.size()); let icon_rect = Rect::from_center_size(bg_rect.center(), (15.0, 15.0)); let offset_matrix = FillStrat::default().affine_to_fill(icon_rect.size(), self.icon.size()); if ctx.is_hot() { ctx.fill(bg_rect, &Color::rgba8(50, 50, 50, 255)); ctx.stroke( Line::new( (0.0, bg_rect.height() - 2.0), (bg_rect.width(), bg_rect.height() - 2.0), ), &Color::rgb8(100, 100, 100), 2.0, ); } ctx.with_child_ctx(icon_rect, |ctx| { ctx.transform(druid::Affine::translate((icon_rect.x0, icon_rect.y0))); self.icon.to_piet(offset_matrix, ctx); }); } }