use crate::widget::{WidgetCommand, WidgetError, WidgetId};
use crate::widget_manager::WidgetBox;
use crate::{SizeConstraints, SystemEvent, Widget, WidgetEvent};
use druid_shell::kurbo::{Point, Rect, Size};
use druid_shell::piet::{PaintBrush, Piet, RenderContext};
use druid_shell::{piet, Region};
pub struct Padding {
child_widget: Option<WidgetBox>,
debug_rendering: bool,
debug_rendering_stroke_brush: PaintBrush,
debug_rendering_stroke_width: f64,
is_hidden: bool,
padding_bottom: f64,
padding_left: f64,
padding_right: f64,
padding_top: f64,
rectangle: Rect,
size_constraints: SizeConstraints,
widget_id: WidgetId,
}
impl Padding {
pub fn new(
widget_id: WidgetId,
debug_rendering_stroke_brush: PaintBrush,
debug_rendering_stroke_width: f64,
padding_left: f64,
padding_top: f64,
padding_right: f64,
padding_bottom: f64,
) -> Self {
Padding {
child_widget: None,
debug_rendering: false,
debug_rendering_stroke_brush,
debug_rendering_stroke_width,
is_hidden: false,
padding_bottom,
padding_left,
padding_right,
padding_top,
rectangle: Rect::default(),
size_constraints: SizeConstraints::default(),
widget_id,
}
}
fn layout_child(&mut self) {
if let Some(child_widget) = &mut self.child_widget {
let padding_size = Size::new(
self.padding_left + self.padding_right,
self.padding_top + self.padding_bottom,
);
let child_size = child_widget
.borrow_mut()
.apply_size_constraints(self.size_constraints.shrink(padding_size));
self.rectangle = self.rectangle.with_size(child_size + padding_size);
child_widget.borrow_mut().set_origin(
self.rectangle.origin()
+ (
0.5 * (self.rectangle.size().width - child_size.width).max(0.0),
0.5 * (self.rectangle.size().height - child_size.height).max(0.0),
),
);
}
else {
self.rectangle = self.rectangle.with_size(*self.size_constraints.maximum());
}
}
}
impl Widget for Padding {
fn apply_size_constraints(&mut self, size_constraints: SizeConstraints) -> Size {
self.size_constraints = size_constraints;
self.layout_child();
self.rectangle.size()
}
fn handle_command(&mut self, widget_command: WidgetCommand) -> Result<(), WidgetError> {
match widget_command {
WidgetCommand::AppendChild(child_widget) => {
self.child_widget = Some(child_widget);
self.layout_child();
}
WidgetCommand::RemoveAllChildren => {
self.child_widget = None;
}
WidgetCommand::RemoveChild(_) => {
println!("`Padding::handle_widget_command(RemoveChild)`: TODO");
}
WidgetCommand::SetDebugRendering(debug_rendering) => {
self.debug_rendering = debug_rendering;
}
WidgetCommand::SetHasFocus(_) => {}
WidgetCommand::SetIsDisabled(_) => {
println!("`Padding::handle_widget_command(SetIsDisabled)`: TODO");
}
WidgetCommand::SetIsHidden(is_hidden) => {
self.is_hidden = is_hidden;
}
WidgetCommand::SetValue(_value) => {}
}
Ok(())
}
fn handle_event(&mut self, system_event: &SystemEvent, widget_events: &mut Vec<WidgetEvent>) {
if let Some(child_widget) = &mut self.child_widget {
child_widget
.borrow_mut()
.handle_event(system_event, widget_events);
}
}
fn paint(&self, piet: &mut Piet, region: &Region) -> Result<(), piet::Error> {
if self.is_hidden {
return Ok(());
}
if let Some(child_widget_rc) = &self.child_widget {
child_widget_rc.borrow().paint(piet, region)?;
}
if self.debug_rendering {
piet.stroke(
self.rectangle,
&self.debug_rendering_stroke_brush,
self.debug_rendering_stroke_width,
);
}
Ok(())
}
fn set_origin(&mut self, origin: Point) {
self.rectangle = self.rectangle.with_origin(origin);
self.layout_child();
}
fn widget_id(&self) -> &WidgetId {
&self.widget_id
}
}